0

I'm working with AngularJs 1.2. I have a problem with $setValidity.

I have a form input with ng-repeat :

<div ng-repeat="(key, value) in addition_page">
    <input ng-model="addition_page[key].name" name="pagename[{{key}}]" not-duplicated="1"> 
</div>

Now I need to use $setValidity on some specify input, but I failed

scope["finish_form"]["pagename[0]"].$setValidity('not-duplicated', false);

I tried to log:

console.log(scope["finish_form"]["pagename[0]"]) => return undefined
console.log(scope["finish_form"]["pagename[{{key}}]"]) => return last input

I inspected element on browser, pagename[0] is existed.

I need help, plz.

Thank you all.

Update:

.directive('notDuplicated', [function() {
            return {
                require: 'ngModel',
                link: function(scope, elem, attr, ngModel) {
                    var val_id = attr.notDuplicated;

                    var setValidity = function(value) {
                        if (value === "") return true;
                        var same_now = [];
                        var same_past = [];
                        angular.element("[not-duplicated=" + val_id + "]").each(function(k, v) {
                            if (angular.element(v).val() === value) {
                                same_now.push(k);
                            }
                            if (ngModel.$modelValue !== "" && angular.element(v).val() === ngModel.$modelValue) {
                                same_past.push(k);
                            }
                        })

                        // mark old input is valid
                        if (same_past.length === 1) {
                            scope["finish_form"]["pagename[" + same_past[0] + "]"].$setValidity('not-duplicated', true);
                        }

                        // mark new inputs is invalid
                        if (same_now.length > 1) {
                            same_now.each(function(k) {
                                scope["finish_form"]["pagename[" + k + "]"].$setValidity('not-duplicated', false);
                            });
                            return false;
                        }
                        return true;

                    }

                    //For DOM -> model validation
                    ngModel.$parsers.unshift(function(value) {
                        var valid = setValidity(value);
                        return valid ? value : undefined;
                    });

                    //For model -> DOM validation
                    ngModel.$formatters.unshift(function(value) {
                        setValidity(value);
                        return value;
                    });
                }
            };
        }]);
5
  • where are you doing this: "scope["finish_form"]["pagename[0]"].$setValidity('not-duplicated', false);"? Are you doing that inside the link function of a custom validation directive? Commented Sep 12, 2014 at 3:35
  • Are you doing that inside the link function of a custom validation directive? => Yes.Inside ngModel.$parsers.unshift and ngModel.$formatters.unshift Commented Sep 12, 2014 at 3:41
  • mmmmmmm, could you please share the rest of that code? Commented Sep 12, 2014 at 3:43
  • I appended my directive. Take a look at that. Thank you. Commented Sep 12, 2014 at 3:51
  • For ngModelController name interpolation {{}} do not work. Look at ng-form directive. Commented Sep 12, 2014 at 4:18

1 Answer 1

1

This happens because the control's name (the one with which it is registered on its parent form) is retrieved during the ngModelController's instantiation, which according to the docs takes place before the pre-linking phase* (so no interpolation yet).

If you inspect the myForm's properties, you will find out that all the inputs are registered as "pagename[{{key}}]".


Take a look at this answer for a more detailed explanation and a possible solution (using an extra directive).

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

1 Comment

@LêTrầnTiếnTrung: Glad to know :) Feel free to also upvote the other answer to let other people know it helped you with your problem.

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.