Trung
Trung

Reputation: 650

AngularJs: using $setValidity on array input

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;
                    });
                }
            };
        }]);

Upvotes: 0

Views: 1016

Answers (1)

gkalpak
gkalpak

Reputation: 48212

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).

Upvotes: 1

Related Questions