Angularjs - How to check for unique inputs and if there is a duplicate mark both as invalid

后端 未结 1 1182
别那么骄傲
别那么骄傲 2021-01-04 06:47

I have a situation where a user needs to enter input into text areas created by ng-repeat. If the user enters a value that has already been entered both the new and existing

相关标签:
1条回答
  • 2021-01-04 07:29

    I think it might because the verifyDuplicate method keeps setting and re-setting the validity of the same model, so the validity of the model triggering method invocation will be based on the last comparison result in the loop.

    One way to solve this is to let the verifyDuplicate method work on the persons collection as a whole, no matter which model change triggers the method invocation, in this example the $setValidity method is not used, instead, a isDuplicate property on the model is set to indicate duplication.

    HTML:

    <ng-form name="personForm">
         <div ng-class="{ 'has-error' :
                personForm.personName.$invalid }">
                <input type='number'
                name="personName"
                ng-class="empty"
                ng-model="person.name"
                ng-change="verifyDuplicate()"/>
         </div>
     </ng-form>
    <div class='error'
            ng-if='person.isDuplicate'>
            Duplicate.
    </div>
    

    JavaScript:

    $scope.verifyDuplicate = function() {
            var sorted, i;
            sorted = $scope.persons.concat().sort(function (a, b) {
                if (a.name > b.name) return 1;
                if (a.name < b.name) return -1;
                return 0;
            });
            for(i = 0; i < $scope.persons.length; i++) {
                sorted[i].isDuplicate = ((sorted[i-1] && sorted[i-1].name == sorted[i].name) || (sorted[i+1] && sorted[i+1].name == sorted[i].name));
            }
        };
    

    JSFiddler: http://jsfiddle.net/luislee818/pkhxkozp/4/

    If we insist using $setValidity, I can think of connecting individual model to its form with "ng-init" directive, however this looks cumbersome and there might be better ways if we go with this approach.

    HTML:

    <ng-form name="personForm">
         <div ng-class="{ 'has-error' :
                personForm.personName.$invalid }">
                <input type='number'
                name="personName"
                ng-init="person.form = personForm"
                ng-class="empty"
                ng-model="person.name"
                ng-change="verifyDuplicate()"/>
         </div>
     </ng-form>
    <div class='error'
            ng-show=
            'personForm.personName.$error.duplicate'>
            Duplicate.
    </div>
    

    JavaScript:

    $scope.verifyDuplicate = function() {
            var sorted, i, isDuplicate;
            sorted = $scope.persons.concat().sort(function (a, b) {
                if (a.name > b.name) return 1;
                if (a.name < b.name) return -1;
                return 0;
            });
            for(i = 0; i < $scope.persons.length; i++) {
                isDuplicate = ((sorted[i-1] && sorted[i-1].name == sorted[i].name) || (sorted[i+1] && sorted[i+1].name == sorted[i].name));
                sorted[i].form.personName.$setValidity('duplicate',!isDuplicate);
            }
        };
    

    JSFiddle: http://jsfiddle.net/luislee818/nzd87f1s/1/

    0 讨论(0)
提交回复
热议问题