2016-05-25 13 views
0

Ich verwende eine Richtlinie zum Festlegen einer Formulargültigkeit. Alles funktioniert entsprechend, aber der boolesche Wert der benutzerdefinierten Gültigkeit kehrt nicht sofort zurück und um genau zu sein, muss ein zusätzlicher Tastendruck ausgeführt werden. Übrigens verwende ich 'element.blur', um die benutzerdefinierte Gültigkeit festzulegen. HierVerzögerung der Form-Setvalidität in AngularJS

ist der HTML-Code:

<!DOCTYPE html> 
<html ng-app="myApp"> 

    <head> 
    <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"> 
    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/flick/jquery-ui.min.css"> 
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> 
    <script type="text/javascript" src="https://code.jquery.com/ui/1.11.2/jquery-ui.min.js"></script> 
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script> 
    <script src="script.js"></script> 
    </head> 

    <body> 
     <form ng-controller="myCtrl" name="bioManagementForm" novalidate> 
     <fieldset ng-repeat="bioEducation in bioEducations" data-ng-form="nestedbioEducationsForm"> 
      Degree: <br /> 
      Availability: -- {{ nestedbioEducationsForm.bio_education_degree.$error.available }} 
      <input class="form-control input-form" ng-model="bioEducation.bio_education_degree" name="bio_education_degree" id="bio_education_degree" auto-complete-validation ui-items="searchDegreeItems"> 
      <span class="errors" id="error-bio-education-degree"> 
         <span ng-if="nestedbioEducationsForm.bio_education_degree.$error.available"> * Not Available <br /></span> 
        </span> 
        School: <br /> 
        Availability: -- {{ nestedbioEducationsForm.bio_education_school.$error.available }} 
        <input class="form-control input-form" type="text" ng-model="bioEducation.bio_education_school" name="bio_education_school" id="bio_education_school" auto-complete-validation ui-items="searchSchoolItems"> 
      <span class="errors" id="error-bio-education-school"> 
         <span ng-if="nestedbioEducationsForm.bio_education_school.$error.available"> * Not Available <br /></span> 
        </span> 
     </fieldset> 
    </form> 
    </body> 
</html> 

Hier ist der JS-Code:

// Code goes here 

var myApp = angular.module('myApp', []); 


myApp.controller('myCtrl', function($scope){ 
    $scope.name = "dean"; 
    $scope.originalBioEducations = [{}]; 
    $scope.bioEducations = angular.copy($scope.originalBioEducations); 
    $scope.searchSchoolItems = ["Don Bosco", "JRU", "UST", "FEU"]; 
    $scope.searchDegreeItems = ["BSIT", "BSED", "ECE", "COE"]; 
}); 

function monkeyPatchAutocomplete() { 
    // Don't really need to save the old fn, 
    // but I could chain if I wanted to 
    var oldFn = $.ui.autocomplete.prototype._renderItem; 

    $.ui.autocomplete.prototype._renderItem = function(ul, item) { 
     var re = new RegExp("(" + this.term + ")", "gi"); 
     var t = item.label.replace(re,"<span style='font-weight:bold;color:#04508e;'>" + this.term + "</span>"); 
     return $("<li></li>") 
     .data("item.autocomplete", item) 
     .append("<a>" + t + "</a>") 
     .appendTo(ul); 
    }; 
} 
monkeyPatchAutocomplete(); 
function remove_duplicates_safe(arr) { 
     var obj = {}; 
     var arr2 = []; 
     for (var i = 0; i < arr.length; i++) { 
      if (!(arr[i] in obj)) { 
       arr2.push(arr[i]); 
       obj[arr[i]] = true; 
      } 
     } 
     return arr2; 
    } 

myApp.directive('autoCompleteValidation', function($timeout){ 
     return { 
      require: 'ngModel', 
      scope: { 
       uiItems: "=" 
      }, 
      link: function(scope, element, attrs, ctrl){ 
       scope.$watchCollection('uiItems', function(val){ 
        items = scope.uiItems.filter(function(n){ return n != undefined }); 
        element.autocomplete({ 
         source: remove_duplicates_safe(items), 
         minLength:2, 
        }); 
        element.bind('blur', function(){ 
         _val = element.val(); 
         _index = items.indexOf(_val); 
         if(_index == -1){ 
          ctrl.$setValidity('available', false); 
          console.log("dean"); 
         }else{ 
          ctrl.$setValidity('available', true); 
          console.log("armada"); 
         } 
        }); 
       }); 
      } 
     } 
    }); 

P. S.

Die App ist ein dynamisches Feld über ng-repeat. Ich verwende auch Data-NG-Form für die dynamischen Validierungen. Beide Eingabefelder werden von der jquery ui Autocomplete ausgeführt. Die Überprüfung sollte erkennen, ob der Wert für das Feld in den Auswahlmöglichkeiten für die automatische Vervollständigung innerhalb eines Arrays (der mit der Bereichsvariablen "Items") enthalten ist. Es sollte einen Fehler auslösen, wenn der Wert im Eingabefeld nicht in den Auswahlmöglichkeiten ist. Hier

ist ein Beispiel in plunkr: http://plnkr.co/edit/2EPuhRiR9OncV8z7q018?p=preview

Antwort

1

Wenn Sie vermeiden möchten, das Hinzufügen keypress Fall, dass Sie $ Validatoren verwenden sollten Eigenschaft auf ngModelController Objekt. Das ist der richtige Weg, um eine Validator-Direktive zu erstellen. Eventuell möchten Sie auch ein Änderungsereignis zu Ihrer automatischen Vervollständigung hinzufügen, so dass Sie $ setViewValue verwenden können.

   scope.$watchCollection('uiItems', function(val){ 
       items = scope.uiItems.filter(function(n){ return n != undefined }); 
       element.autocomplete({ 
        source: remove_duplicates_safe(items), 
        minLength:2, 
        change: function() { 
         ctrl.$setViewValue(element.val()); 
        } 
       }); 
      }); 

      ctrl.$validators.available = function (modelValue, viewValue) { 
       var value = modelValue || viewValue; 
       if (items) { 
       var _index = items.indexOf(value); 

       return _index !== -1; 
       } 
      } 

Plunker: http://plnkr.co/edit/pcARNdakhEouqnCIQ2Yt?p=preview

BTW. Erstelle keine globalen Variablen beim Fliegen, das Hinzufügen von _ bei der Namensbildung macht sie nicht lokal oder privat.