Проверка триггера всех полей в Angular Форма отправки

Я использую этот метод: http://plnkr.co/edit/A6gvyoXbBd2kfToPmiiA?p=preview только для проверки полей размытия. Это прекрасно работает, но я также хотел бы их проверить (и, таким образом, показать ошибки для этих полей, если они есть), когда пользователь нажимает кнопку "отправить" (не представляет собой реальный запрос, но вызывает вызов функции n-click для функции)

Есть ли способ снова активировать проверку во всех полях при нажатии этой кнопки?

Ответ 1

Для меня работала функция $setSubmitted, которая сначала отображается в документах angular в версии 1.3.20.

В событии клика, где я хотел вызвать проверку, я сделал следующее:

vm.triggerSubmit = function() {
    vm.homeForm.$setSubmitted();
    ...
}

Это все, что мне понадобилось. Согласно документам, "Устанавливает форму в отправленное состояние". Он упомянул здесь.

Ответ 2

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

angular.forEach($scope.myForm.$error.required, function(field) {
    field.$setDirty();
});

а затем вы можете проверить, действительна ли ваша форма, используя:

if($scope.myForm.$valid) {
    //Do something
}   

и, наконец, я думаю, вы бы хотели изменить свой маршрут, если все выглядит хорошо:

$location.path('/somePath');

Изменить: форма не будет регистрироваться в области действия до тех пор, пока событие отправки не будет запущено. Просто используйте директиву ng-submit для вызова функции и оберните ее выше в этой функции, и она должна работать.

Ответ 3

Вы можете использовать Angular -Validator, чтобы делать то, что вы хотите. Это глупо прост в использовании.

Он будет:

  • Проверять только поля на $dirty или на submit
  • Предотвращать отправку формы, если она недействительна
  • Показать пользовательское сообщение об ошибке после того, как поле $dirty или форма отправлена ​​

См. демонстрацию

Пример

<form angular-validator 
       angular-validator-submit="myFunction(myBeautifulForm)"
       name="myBeautifulForm">
       <!-- form fields here --!>
    <button type="submit">Submit</button>
</form>

Если поле не передает validator, пользователь не сможет отправить форму.

За дополнительной информацией обращайтесь Angular - примеры использования и примеры.

Отказ от ответственности: я являюсь автором Angular -Validator

Ответ 4

В случае, если кто-то вернется к этому позже... Ни одно из вышеперечисленных не помогло мне. Таким образом, я выкопал в мужество angular проверки формы и нашел функцию, которую они вызывают для выполнения валидаторов в заданном поле. Это свойство удобно назвать $validate.

Если у вас есть именованная форма myForm, вы можете программным способом вызвать myForm.my_field.$validate() для выполнения проверки поля. Например:

<div ng-form name="myForm">
    <input required name="my_field" type="text" ng-blur="myForm.my_field.$validate()">
</div>

Обратите внимание, что вызов $validate имеет последствия для вашей модели. Из документов angular для ngModelCtrl. $Validate:

Запускает каждый зарегистрированный валидатор (первые синхронные валидаторы, а затем асинхронные валидаторы). Если срок действия изменится на недействительный, модель будет установлена ​​на undefined, если ngModelOptions.allowInvalid не является истинным. Если действительность изменится на действительную, она установит модель на последнюю доступную допустимую $modelValue, то есть либо последнее проанализированное значение, либо последнее значение, заданное из области.

Итак, если вы планируете что-то делать с недопустимым значением модели (например, выскакивая сообщение, сообщающее им об этом), вам нужно убедиться, что для allowInvalid установлено значение true.

Ответ 5

Ну, способ angular - позволить ему обрабатывать валидацию, - так как это происходит при каждой модификации модели - и показывать результат только пользователю, когда вы хотите.

В этом случае вы решаете, когда показывать ошибки, вам просто нужно установить флаг: http://plnkr.co/edit/0NNCpQKhbLTYMZaxMQ9l?p=preview

Насколько я знаю, проблема связана с angular, чтобы иметь более расширенный контроль формы. Поскольку он не решен, я использовал бы это вместо того, чтобы изобретать все существующие методы проверки.

edit: Но если вы настаиваете на своем пути, вот ваша измененная скрипка с проверкой перед отправкой. http://plnkr.co/edit/Xfr7X6JXPhY9lFL3hnOw?p=preview Контроллер передает событие при нажатии кнопки, а директива выполняет магию проверки.

Ответ 6

Один из подходов - заставить все атрибуты быть грязными. Вы можете сделать это в каждом контроллере, но он становится очень грязным. Было бы лучше иметь общее решение.

Самый простой способ, о котором я мог думать, - использовать директиву

  • он будет обрабатывать атрибут submit
  • он выполняет итерацию по всем полям формы и помечает грязные поля
  • он проверяет, действительна ли форма до вызова функции отправки

Вот директива

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

И обновите форму html, например:

 <form ng-submit='justDoIt()'>

становится:

 <form name='myForm' novalidate submit='justDoIt()'>

См. полный пример здесь: http://plunker.co/edit/QVbisEK2WEbORTAWL7Gu?p=preview

Ответ 7

Основываясь на ответе Тилака, я смог придумать это решение...

Поскольку в моих полях формы отображаются только сообщения проверки, если поле недействительно и было затронуто пользователем, я смог использовать этот код, запускаемый кнопкой, чтобы показать мои недопустимые поля:

// 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 -->

Ответ 8

Вот моя глобальная функция для отображения сообщений об ошибках формы.

 function show_validation_erros(form_error_object) {
        angular.forEach(form_error_object, function (objArrayFields, errorName) {
            angular.forEach(objArrayFields, function (objArrayField, key) {
                objArrayField.$setDirty();
            });
        });
    };

И в моих любых контроллерах

if ($scope.form_add_sale.$invalid) { 
    $scope.global.show_validation_erros($scope.form_add_sale.$error);
}

Ответ 9

Мне нравится этот подход при обработке проверки при нажатии кнопки.

  • Нет необходимости вызывать что-либо из контроллера,

  • все это обрабатывается с помощью директивы.

on github

Ответ 10

Вы можете попробовать следующее:

// 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>

Ответ 11

Я сделал что-то следующее, чтобы заставить его работать.

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

В вашем контроллере вы можете сделать;

addHeader(form, header){
        let self = this;
        form.$submitted = true;
        ... 
    }

Вам также нужен 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%;
    }

Ответ 12

Примечание: этот ответ немного взломан, который был полезен для Angular 1.2 и более ранних версий, которые не обеспечивали простой механизм.

Проверка выполняется в событии change, поэтому некоторые вещи, такие как изменение значений программным способом, не будут запускать его. Но запуск события изменения вызовет проверку. Например, с помощью jQuery:

$('#formField1, #formField2').trigger('change');