Używam tej metody: http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview, aby sprawdzać tylko pola przy rozmyciu. Działa to dobrze, ale chciałbym również je zweryfikować (a tym samym pokazać błędy tych pól, jeśli występują), gdy użytkownik kliknie przycisk `` prześlij '' (nie jest to prawdziwe przesłanie, ale wywołanie funkcji data-ng-click)
Czy istnieje sposób, aby ponownie uruchomić walidację wszystkich pól po kliknięciu tego przycisku?
Odpowiedzi:
U mnie zadziałało użycie
$setSubmitted
funkcji, która po raz pierwszy pojawia się w dokumentach kątowych w wersji 1.3.20.W przypadku kliknięcia, w którym chciałem uruchomić walidację, wykonałem następujące czynności:
vm.triggerSubmit = function() { vm.homeForm.$setSubmitted(); ... }
To było wszystko, czego potrzebowałem. Zgodnie z dokumentacją „Ustawia formularz na stan przedłożony”. Jest to tutaj wymienione .
źródło
ng-messages
i wyświetlasz je tylko wtedy, gdy $ error && $ dirty .form
... Musiałem przelecieć przez wszystkie wejścia i wywołać$setDirty()
je.Wiem, że na odpowiedź jest trochę za późno, ale wszystko, co musisz zrobić, to zabrudzić wszystkie formularze. Spójrz na następujący fragment:
angular.forEach($scope.myForm.$error.required, function(field) { field.$setDirty(); });
a następnie możesz sprawdzić, czy Twój formularz jest ważny za pomocą:
if($scope.myForm.$valid) { //Do something }
i na koniec myślę, że chciałbyś zmienić trasę, jeśli wszystko wygląda dobrze:
$location.path('/somePath');
Edycja : formularz nie zarejestruje się w zakresie, dopóki nie zostanie wyzwolone zdarzenie przesyłania. Po prostu użyj dyrektywy ng-submit, aby wywołać funkcję i zawinąć powyższe funkcje w tę funkcję, a powinno działać.
źródło
ng-submit
dyrektywy wyzwalającej programowo ?ng-submit
po prostu wiąże funkcję ze zdarzeniem przesyłania, dlaczego nie wywołać tej funkcji?Na wypadek, gdyby ktoś wrócił do tego później ... Żadne z powyższych nie zadziałało dla mnie. Więc zagłębiłem się w wnętrzności walidacji formy kątowej i znalazłem funkcję, którą wywołują, aby wykonać walidatory na danym polu. Ta właściwość jest dogodnie nazywana
$validate
.Jeśli masz nazwany formularz
myForm
, możesz programowo wywołać wmyForm.my_field.$validate()
celu wykonania walidacji pola. Na przykład:<div ng-form name="myForm"> <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()"> </div>
Pamiętaj, że wywołanie
$validate
ma wpływ na Twój model. Z dokumentacji kątowej dla ngModelCtrl. $ Validate:Więc jeśli planujesz zrobić coś z nieprawidłową wartością modelu (np. Wyświetlenie komunikatu informującego o tym), musisz się upewnić
allowInvalid
jest ustawiony natrue
dla twojego modelu.źródło
allowInvalid
można przeczytać tutaj: github.com/angular/angular.js/issues/10035Możesz użyć Angular-Validator, aby robić, co chcesz. To głupie, proste w użyciu.
To będzie:
$dirty
lub włączonesubmit
$dirty
lub formularzaZobacz demo
Przykład
<form angular-validator angular-validator-submit="myFunction(myBeautifulForm)" name="myBeautifulForm"> <!-- form fields here --> <button type="submit">Submit</button> </form>
Jeśli pole nie spełnia
validator
warunków, użytkownik nie będzie mógł wysłać formularza.Aby uzyskać więcej informacji, zobacz przykłady użycia i przykłady użycia walidatorów kątowych .
Zastrzeżenie: jestem autorem Angular-Validator
źródło
Cóż, kątowym sposobem byłoby pozwolić mu zająć się walidacją - ponieważ robi to przy każdej zmianie modelu - i pokazać wynik użytkownikowi tylko wtedy, gdy chcesz.
W tym przypadku decydujesz, kiedy pokazać błędy, wystarczy ustawić flagę: http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview
O ile wiem, zgłoszony został problem do kątowego, aby umożliwić nam bardziej zaawansowaną kontrolę nad formularzami. Ponieważ nie został rozwiązany, użyłbym tego zamiast wymyślać na nowo wszystkie istniejące metody walidacji.
edycja: Ale jeśli nalegasz na swoją drogę, oto twoje zmodyfikowane skrzypce z walidacją przed przesłaniem. http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview Kontroler emituje zdarzenie po kliknięciu przycisku, a dyrektywa wykonuje magię walidacji.
źródło
Jednym ze sposobów jest wymuszenie zabrudzenia wszystkich atrybutów. Możesz to zrobić w każdym kontrolerze, ale robi się bardzo bałagan. Lepiej byłoby mieć ogólne rozwiązanie.
Najłatwiejszym sposobem, o jakim przyszło mi do głowy, było użycie dyrektywy
Oto dyrektywa
myModule.directive('submit', function() { return { restrict: 'A', link: function(scope, formElement, attrs) { var form; form = scope[attrs.name]; return formElement.bind('submit', function() { angular.forEach(form, function(field, name) { if (typeof name === 'string' && !name.match('^[\$]')) { if (field.$pristine) { return field.$setViewValue(field.$value); } } }); if (form.$valid) { return scope.$apply(attrs.submit); } }); } }; });
I zaktualizuj swój formularz html, na przykład:
staje się:
<form name='myForm' novalidate submit='justDoIt()'>
Zobacz pełny przykład tutaj: http://plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview
źródło
Oto moja globalna funkcja do wyświetlania komunikatów o błędach formularza.
function show_validation_erros(form_error_object) { angular.forEach(form_error_object, function (objArrayFields, errorName) { angular.forEach(objArrayFields, function (objArrayField, key) { objArrayField.$setDirty(); }); }); };
A w moich kontrolerach
if ($scope.form_add_sale.$invalid) { $scope.global.show_validation_erros($scope.form_add_sale.$error); }
źródło
Na podstawie odpowiedzi Thilaka udało mi się wymyślić takie rozwiązanie ...
Ponieważ moje pola formularza pokazują komunikaty walidacji tylko wtedy, gdy pole jest nieprawidłowe i zostało dotknięte przez użytkownika, mogłem użyć tego kodu uruchamianego przez przycisk, aby wyświetlić moje nieprawidłowe pola:
// Show/trigger any validation errors for this step angular.forEach(vm.rfiForm.stepTwo.$error, function(error) { angular.forEach(error, function(field) { field.$setTouched(); }); }); // Prevent user from going to next step if current step is invalid if (!vm.rfiForm.stepTwo.$valid) { isValid = false; }
<!-- form field --> <div class="form-group" ng-class="{ 'has-error': rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched && rfi.rfiForm.stepTwo.Parent_Suffix__c.$invalid }"> <!-- field label --> <label class="control-label">Suffix</label> <!-- end field label --> <!-- field input --> <select name="Parent_Suffix__c" class="form-control" ng-options="item.value as item.label for item in rfi.contact.Parent_Suffixes" ng-model="rfi.contact.Parent_Suffix__c" /> <!-- end field input --> <!-- field help --> <span class="help-block" ng-messages="rfi.rfiForm.stepTwo.Parent_Suffix__c.$error" ng-show="rfi.rfiForm.stepTwo.Parent_Suffix__c.$touched"> <span ng-message="required">this field is required</span> </span> <!-- end field help --> </div> <!-- end form field -->
źródło
Uwaga: wiem, że to hack, ale był przydatny w Angular 1.2 i wcześniejszych, które nie zapewniały prostego mechanizmu.
Walidacja rozpoczyna się w zdarzeniu zmiany , więc niektóre rzeczy, takie jak programowa zmiana wartości, nie wyzwoli go. Ale wyzwolenie zdarzenia zmiany wyzwoli walidację. Na przykład z jQuery:
$('#formField1, #formField2').trigger('change');
źródło
angular way
.Podoba mi się to podejście do obsługi walidacji po kliknięciu przycisku.
Nie ma potrzeby wywoływania czegokolwiek z kontrolera,
wszystko jest obsługiwane za pomocą dyrektywy.
na github
źródło
Możesz spróbować tego:
// The controller $scope.submitForm = function(form){ //Force the field validation angular.forEach(form, function(obj){ if(angular.isObject(obj) && angular.isDefined(obj.$setDirty)) { obj.$setDirty(); } }) if (form.$valid){ $scope.myResource.$save(function(data){ //.... }); } }
<!-- FORM --> <form name="myForm" role="form" novalidate="novalidate"> <!-- FORM GROUP to field 1 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field1.$invalid && myForm.field1.$dirty }"> <label for="field1">My field 1</label> <span class="nullable"> <select name="field1" ng-model="myresource.field1" ng-options="list.id as list.name for list in listofall" class="form-control input-sm" required> <option value="">Select One</option> </select> </span> <div ng-if="myForm.field1.$dirty" ng-messages="myForm.field1.$error" ng-messages-include="mymessages"></div> </div> <!-- FORM GROUP to field 2 --> <div class="form-group" ng-class="{ 'has-error' : myForm.field2.$invalid && myForm.field2.$dirty }"> <label class="control-label labelsmall" for="field2">field2</label> <input name="field2" min="1" placeholder="" ng-model="myresource.field2" type="number" class="form-control input-sm" required> <div ng-if="myForm.field2.$dirty" ng-messages="myForm.field2.$error" ng-messages-include="mymessages"></div> </div> </form> <!-- ... --> <button type="submit" ng-click="submitForm(myForm)">Send</button>
źródło
Zrobiłem coś później, aby to zadziałało.
<form name="form" name="plantRegistrationForm"> <div ng-class="{ 'has-error': (form.$submitted || form.headerName.$touched) && form.headerName.$invalid }"> <div class="col-md-3"> <div class="label-color">HEADER NAME <span class="red"><strong>*</strong></span></div> </div> <div class="col-md-9"> <input type="text" name="headerName" id="headerName" ng-model="header.headerName" maxlength="100" class="form-control" required> <div ng-show="form.$submitted || form.headerName.$touched"> <span ng-show="form.headerName.$invalid" class="label-color validation-message">Header Name is required</span> </div> </div> </div> <button ng-click="addHeader(form, header)" type="button" class="btn btn-default pull-right">Add Header </button> </form>
W swoim kontrolerze możesz to zrobić;
addHeader(form, header){ let self = this; form.$submitted = true; ... }
Potrzebujesz też CSS;
.label-color { color: $gray-color; } .has-error { .label-color { color: rgb(221, 25, 29); } .select2-choice.ui-select-match.select2-default { border-color: #e84e40; } } .validation-message { font-size: 0.875em; } .max-width { width: 100%; min-width: 100%; }
źródło
Aby zweryfikować wszystkie pola mojego formularza, kiedy chcę, przeprowadzam walidację każdego pola kontrolek $$ w następujący sposób:
angular.forEach($scope.myform.$$controls, function (field) { field.$validate(); });
źródło