Angularjs: Form validation on input field generated by directive -
i have built directive generates input field based on meta ($scope.meta
) data. problem supporting angular's form validation.
plunkr: http://plnkr.co/edit/afr5cwyywglcecs6h6dr?p=preview
explanation: directive takes meta
parameter describes input field type , other related information render field. attributes defined on directive copied element , replace directive after compilation , linking.
view:
<form name="userform"> <!-- username --> <poly-field ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field> <p ng-show="userform.username.$error.minlength" class="help-block">username short.</p> <p ng-show="userform.username.$error.maxlength" class="help-block">username long</p> <!-- email --> <poly-field ng-model="storage" meta="meta" key="email" name="email" ng-required></poly-field> <p ng-show="userform.email.$error.minlength" class="help-block">email short.</p> <p ng-show="userform.email.$error.maxlength" class="help-block">email long</p> </form>
entering username longer or shorter allowed should show me error. skipping email field show me error too.
here view source-code after applying directive:
<form name="userform" class="ng-pristine ng-valid ng-valid-required"> <!-- username --> <input type="undefined" ng-model="storage.username" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8" class="ng-scope ng-valid-minlength ng-dirty ng-valid ng-valid-maxlength"> <p ng-show="userform.username.$error.minlength" class="help-block ng-hide">username short.</p> <p ng-show="userform.username.$error.maxlength" class="help-block ng-hide">username long</p> <!-- email --> <input type="undefined" ng-model="storage.email" meta="meta" key="email" name="email" ng-required="" class="ng-scope ng-valid ng-valid-required ng-dirty"> <p ng-show="userform.email.$error.minlength" class="help-block ng-hide">email short.</p> <p ng-show="userform.email.$error.maxlength" class="help-block ng-hide">email long</p> </form>
here model view , directive working with, it's declared in parentctrl.
$scope.storage = { username: "kitkat", email: "flying@kitkat.com" };
that's meta information, tell how input field (is text? date? etc.)
$scope.meta = { username: { type: "text" }, email: { type: "text" } };
directive declaration:
app.directive('polyfield', function($compile) { var linkfn = function(scope, element, attributes) { // create input element depending on type var template = document.createelement("input"); template.type = scope.storage[attributes.key].type; // copy attributes (var attr in attributes.$attr) { if (attributes.$attr[attr] == 'ng-model') { template.setattribute('ng-model', attributes[attr] + '.' + attributes.key); } else { template.setattribute(attributes.$attr[attr], attributes[attr]); } } // template compilation, linking , element replacement template = angular.element(template.outerhtml); var linktemplate = $compile(template); var domelement = linktemplate(scope); element.replacewith(domelement); } var directive = { restrict: 'e', scope: { meta: '=', storage: '=ngmodel', key: '=', }, link: linkfn }; return directive; });
some thoughts:
each directive creates isolated scope, so, inside directive userform
unseen, however, storage
(ng-model) two-way binded seen directive's scope , parent scope, if userform sees what's inside storage
should ok, isn't it?
i tried pass userform
directive scope:
// directive scope: { meta: '=', storage: '=ngmodel', key: '=', userform: '=' } // template <poly-field user-form="userform" ng-model="storage" meta="meta" key="username" name="username" ng-minlength="3" ng-maxlength="8"></poly-field>
but no effect.
when directives scope, userform
field see input field $dirty: false
, $invalid: true
, , after typed username/email field,
in source code it's seems validation classes applied correctly: ng-valid-minlength
ng-dirty
ng-invalid
ng-invalid-maxlength
still, no validation errors shown.
is there can it?
in order angular's form-validation de able kick in, ngmodel
looks parent ngform
/form
directive during controller's instantiation phase (before pre-linking phase).
since compile , link element before adding dom there no parent element @ time, fails register.
you need first insert element dom , compile , link it.
Comments
Post a Comment