15

I am trying to validate some form fields which are given to me from a backend endpoint...

So basically the input elements are dynamically created inside a ng-repeat. Therefore, the input attributes are also dynamically added, such as the type, name, etc...

However because the name attribute is dynamically added, when I try to validate it, like this, for example:

myForm.elName.$valid

It doesn't return anything because at this point, it doesn't know what elName is.

I created a jsFiddle to demonstrate the problem: http://jsfiddle.net/peduarte/HB7LU/1889/

Any help or advice will be much appreciated!

FANX.

EDIT:
I've been referring to this AWESOME documentation: http://docs.angularjs.org/api/ng.directive:input.email

2
  • Please, develop. Why do you regret every seconds of angularJS? Commented Mar 20, 2014 at 6:36
  • 1
    This is what you are looking for stackoverflow.com/questions/27071413/… Commented Nov 21, 2014 at 22:56

1 Answer 1

36

Try my custom directive:

myApp.directive("dynamicName",function($compile){
  return {
      restrict:"A",
      terminal:true,
      priority:1000,
      link:function(scope,element,attrs){
          element.attr('name', scope.$eval(attrs.dynamicName));
          element.removeAttr("dynamic-name");
          $compile(element)(scope);
      }
   };
});

Use it:

<input dynamic-name="field.name"
       type="{{ field.type }}"
       placeholder="{{ field.name }}"
       ng-model="field.value"
       required>

DEMO

Explanation of the problem:

By default, input elements using ngModelController (ng-model) call FormController.$addControl when they are linked to register itself and expose a property on the FormController with the name property of the input which is {{ field.name }} in this case. Therefore, even though the control is registered but you don't have exposed properties on FormController with named email, firstName, you only have {{ field.name }} referencing the last input item

Explanation of the solution:

In this solution, I created a custom directive to replace the {{ field.name }} with the correct name at runtime.

For more information why I have to use terminal:true, and priority:1000, check out this discussion: Add directives from directive in AngularJS

Sign up to request clarification or add additional context in comments.

6 Comments

A isolated scope can be used instead of scope.$eval: scope: { dynamicName: '=' } in the directive configuration then simply scope.dynamicName inside link.
@Hugo Wood: I don't think we need isolate scope here. The purpose of this directive is to modify the current element based on current scope. Using current scope is more appropriate IMO.
can I loop through error messages dynamically ? they are hardcoded in the demo
@sisimh: yes, just use javascript bracket notation: {{ myForm[formFields[0].name].$valid }}: jsfiddle.net/3qu3tu6f
thank you for ur reply @KhanhTO , actually i am thinking of returning the validation error from the directive it self , in that case how can I concat form name with the error fields like what u did except that i dont have "myForm" hardcoded
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.