2016-07-16 4 views
1

Я пытаюсь проверить форму, где нет дублирования значений. У меня есть сайт, содержащий список адресов Ip. В моем из можно добавить много адресов, но они должны быть уникальными.Угловая проверка дублирования ввода

HTML:

<div class="col-sm-6"> 
    <ul style="list-style-type: none;-webkit-padding-start: 0px;margin-bottom:0px"> 
    <li ng-repeat="ip in site.ips track by $index | orderBy: '+ip.ip_adress'" style="margin-bottom:0px"> 
     <ng-form name="ipForm">      
     <div class="input-group" style="margin-top:5px" ng-class="{ 'has-error' : !ipForm.ip_adress.$error.duplicate && ipForm.ip_adress.$invalid && !ipForm.ip_adress.$pristine }"> 
      <input type="text" class="form-control input-sm" name="ip_adress" 
      ng-pattern='/^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$/' 
      style="display: inline;" 
      ng-model="ip.ip_adress" 
      placeholder="{{translate('config.sites.msg.site.ip.adress')}}"      
      required /> 
      <div class="input-group-addon"> 
       <i class="glyphicon glyphicon-remove-circle" ng-click="removeIp(site, ip, $index)"></i> 
      </div> 
     </div> 
     </ng-form> 

    </li> 
    </ul> 
</div> 

Я также попытался с ng-change:"verifyDuplicate()" и вот JS

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


      } 

и это выдаст ошибку: Cannot read property 'ips' of undefined. Я также пробовал этот пример, но он не работает.

Любые предложения, пожалуйста?

+0

можно показать структуру $ scope.sites –

+0

в форме (html), вы используете 'site.ips' в качестве источника (' site.ips' должен быть массив), а в 'verifyDuplicate' вы используете' sites [0 ] '(' sites' должен быть массивом). Это должно совпадать. Попробуйте '$ scope.site.ips [0]' in js –

+1

Кроме того, у вас много ошибок в вашем коде, если вы хотите установить подтверждение '$ duplicate', вы ** должны ** использовать директиву, иначе форма будет действительна. – developer033

ответ

1

Вы должны построить директиву, если вы хотите контролировать validity ваших входов, то ваша форма будет $invalid.

Вот простой демо, который вы можете скопировать в свой код:

angular.module('app', ['ngMessages']) 
 
    .controller('mainCtrl', function($scope) { 
 
    $scope.site = {}; 
 
    $scope.site.ips = ['172.16.254.1', '255.255.255.255', '111.111.111.111'] 
 
    }) 
 

 
    .directive('duplicate', function() { 
 
    return { 
 
     restrict: 'A', 
 
     scope: { 
 
     index: '@', 
 
     array: '@' 
 
     }, 
 
     require: 'ngModel', 
 
     link: function(scope, element, attrs, ngModel) { 
 
     if (!ngModel) return; 
 

 
     scope.$watch(function() { 
 
      return ngModel.$modelValue 
 
      }, 
 
      function() { 
 
      validate(); 
 
      }); 
 

 
     var validate = function() { 
 
      scope.array = JSON.parse(scope.array); 
 
      var elem_value = element.val(); 
 
      var obj = scope.array.find(function(value, i) { 
 
      return value == elem_value && scope.index != i; 
 
      }); 
 
      ngModel.$setValidity('duplicate', obj ? false : true); 
 
     }; 
 
     } 
 
    } 
 
    });
<!DOCTYPE html> 
 
<html ng-app="app"> 
 

 
<head> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script> 
 
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" /> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script> 
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script> 
 
</head> 
 

 
<body ng-controller="mainCtrl"> 
 
    <div class="col-sm-6"> 
 
    <ul style="list-style-type: none;-webkit-padding-start: 0px;margin-bottom:0px"> 
 
     <li ng-repeat="ip in site.ips track by $index" style="margin-bottom:0px"> 
 
     <ng-form name="ipForm"> 
 
      <div class="input-group" style="margin-top:5px" ng-class="{ 'has-error' : ipForm.ip_address.$invalid }"> 
 
      <input type="text" name="ip_address" class="form-control input-sm" ng-pattern='/^([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})[.]([0-9]{1,3})$/' style="display: inline;" ng-model="site.ips[$index]" placeholder="{{translate('config.sites.msg.site.ip.adress')}}" 
 
      required duplicate index="{{$index}}" array="{{site.ips}}" /> 
 
      <div class="input-group-addon"> 
 
       <i class="glyphicon glyphicon-remove-circle" ng-click="removeIp(site, ip, $index)"></i> 
 
      </div> 
 
      <div class="help-block" ng-messages="ipForm.ip_address.$error" ng-if="ipForm.ip_address.$touched"> 
 
       <p ng-message="required">This field is required</p> 
 
       <p ng-message="minlength">This field is too short</p> 
 
       <p ng-message="maxlength">This field is too long</p> 
 
       <p ng-message="pattern">This needs to be a valid ip</p> 
 
       <p ng-message="duplicate">Duplicate!</p> 
 
      </div> 
 
      </div> 
 
     </ng-form> 
 
     </li> 
 
    </ul> 
 
    </div> 
 
</body> 
 

 
</html>

Примечание: Это просто указать вам на правильном направлении, может быть, это не самый эффективный способ сделать это.

В любом случае, я надеюсь, что это поможет.

Смежные вопросы