1
 <FORM>
 <DIV class="outer-class">
      <INPUT class="toValidate" type = "text"/>
      <INPUT class="somethingElse" type= "text"/>
      <INPUT class="toValidate" type ="text"/>
 </DIV>
 <DIV class="outer-class">
      <INPUT class="toValidate" type = "text"/>
      <INPUT class="somethingElse" type= "text"/>
      <INPUT class="toValidate" type ="text"/>
 </DIV>
 <INPUT type="submit"/>
 </FORM>

My question is: How do I ensure that for the form to be valid, the nested toValidates have a unique value but only within the same outer div? I am guessing this logic should go in an OuterClassDirective, but I can't seem to figure out what the logic should look like?

Any advice would be appreciated.

Thanks!

Abraham P
  • 15,029
  • 13
  • 58
  • 126

2 Answers2

1

The 'tabs' and 'pane' directives on the Angular home page solve a similar issue -- the child 'pane' directives need to communicate with the parent 'tabs' directive.

Define a controller on the outerclass directive, and then define a method on the controller (use this not $scope). Then require: '^outerclass' in the toValidate directive. In the toValidate link function, you can $watch for value changes and call the method on the outerclass controller to pass the value up. Do the validation in the outerclass directive.

See also 'this' vs $scope in AngularJS controllers.

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
1

What about this. Your outerClassDirective should have a controller, which will store used values in an array. It will transclude the input fields in its body. Your toValidate directive requires outerClassDirective and adds the model value to the array, making it invalid if exists.

Here is a try (untested):

app.directive('outerClass', function() {
   var values = [];
   var valid = true;
   return {
      template: '<div ng-transclude></div>',
      transclude: true,
      replace: true,
      require: 'ngModel',
      controller: function() {
         this.addValue: function(value) {
            valid = values.indexOf(value) > -1;
            values.push(value);
         };
      },
      link: function(scope, elm, attrs, ctrl) {
         ctrl.$setValidity('toValidate', valid)
      }
   };
});

app.directive('toValidate', function() {
   return {
        require: '^outerClass',
        link: function(scope, elm, attrs, ctrl) {
           ctrl.addValue(attrs.value);
        } 
      }
   };
});
asgoth
  • 35,552
  • 12
  • 89
  • 98
  • I may have accepted prematurely - I've fixed the syntax errors, and seem to now get the following: Error: No controller: ngModel Any ideas? Thanks! – Abraham P Jan 09 '13 at 08:23
  • Your outerClass tag needs a ng-model attribute. – asgoth Jan 09 '13 at 08:28
  • Ahh yes. Thanks. Any suggestions for what would make a good ng-model value? I've currently set it to ng-model="$index" (its nested in an ng-repeat), as (I don't think?) I need to tie the divs model to anything? – Abraham P Jan 09 '13 at 08:32
  • You don't understand the setup. If one of the input tags detects that its value already exists, it will flag the model on the parent tag (outerClass) as invalid. So you just need a new model object (e.g. groupOfFields), which you can test on form submit (e.g if(groupOfFields.$invalid) ...). – asgoth Jan 09 '13 at 08:39