Подтвердить поле формы только для отправки или ввода пользователем

У меня есть поля формы, которые проверяются с помощью required. Проблема в том, что ошибка отображается сразу после визуализации формы. Я хочу, чтобы он отображался только после ввода пользователем текстового поля или отправки.

Как это реализовать?

Ответ 1

Используйте флаг $dirty, чтобы показать ошибку только после того, как пользователь взаимодействует с входом:

<div>
  <input type="email" name="email" ng-model="user.email" required />
  <span ng-show="form.email.$dirty && form.email.$error.required">Email is required</span>
</div>

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

<form ng-submit="submit()" name="form" ng-controller="MyCtrl">
  <div>
    <input type="email" name="email" ng-model="user.email" required />
    <span ng-show="(form.email.$dirty || submitted) && form.email.$error.required">
      Email is required
    </span>
  </div>

  <div>
    <button type="submit">Submit</button>
  </div>
</form>
function MyCtrl($scope){
  $scope.submit = function(){
    // Set the 'submitted' flag to true
    $scope.submitted = true;
    // Send the form to server
    // $http.post ...
  } 
};

Тогда, если все, что JS внутри выражения ng-show слишком много выглядит для вас, вы можете абстрагировать его на отдельный метод:

function MyCtrl($scope){
  $scope.submit = function(){
    // Set the 'submitted' flag to true
    $scope.submitted = true;
    // Send the form to server
    // $http.post ...
  }

  $scope.hasError = function(field, validation){
    if(validation){
      return ($scope.form[field].$dirty && $scope.form[field].$error[validation]) || ($scope.submitted && $scope.form[field].$error[validation]);
    }
    return ($scope.form[field].$dirty && $scope.form[field].$invalid) || ($scope.submitted && $scope.form[field].$invalid);
  };

};
<form ng-submit="submit()" name="form">
  <div>
    <input type="email" name="email" ng-model="user.email" required />
    <span ng-show="hasError('email', 'required')">required</span>
  </div>

  <div>
    <button type="submit">Submit</button>
  </div>
</form>

Ответ 2

Если вы хотите показывать сообщения об ошибках при отправке формы, вы можете использовать условие form.$submitted, чтобы проверить, была ли сделана попытка отправить форму. Проверьте следующий пример.

<form name="myForm" novalidate ng-submit="myForm.$valid && createUser()">
  <input type="text" name="name" ng-model="user.name" placeholder="Enter name of user" required>
  <div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
    <div ng-message="required">Please enter user name.</div>
  </div>

  <input type="text" name="address" ng-model="user.address" placeholder="Enter Address" required ng-maxlength="30">
  <div ng-messages="myForm.name.$error" ng-if="myForm.$submitted">
    <div ng-message="required">Please enter user address.</div>
    <div ng-message="maxlength">Should be less than 30 chars</div>
  </div>

  <button type="submit">
    Create user
  </button>
</form>

Ответ 3

Вы можете использовать состояние формы angularjs form.$submitted. Первоначально значение form.$submitted будет false и станет true после успешной отправки формы.

Ответ 4

Эрик Айнер,

Пожалуйста, используйте $dirty (поле было изменено) и $invalid (Содержимое поля недействительно).

Пожалуйста, проверьте приведенные ниже примеры для проверки формы angular

1)

Пример проверки HTML для ввода пользователем ввода:

<form  ng-app="myApp"  ng-controller="validateCtrl" name="myForm" novalidate>
  <p>Email:<br>
    <input type="email" name="email" ng-model="email" required>
    <span ng-show="myForm.email.$dirty && myForm.email.$invalid">
      <span ng-show="myForm.email.$error.required">Email is required.</span>
      <span ng-show="myForm.email.$error.email">Invalid email address.</span>
      </span>
  </p>
    </form>

2)

Пример проверки HTML/Js для пользователя:

      <form  ng-app="myApp"  ng-controller="validateCtrl" name="myForm" novalidate form-submit-validation="">
      <p>Email:<br>
        <input type="email" name="email" ng-model="email" required>
        <span ng-show="submitted || myForm.email.$dirty && myForm.email.$invalid">
          <span ng-show="myForm.email.$error.required">Email is required.</span>
          <span ng-show="myForm.email.$error.email">Invalid email address.</span>
          </span>
      </p>
<p>
  <input type="submit">
</p>
</form>

Пользовательская директива:

app.directive('formSubmitValidation', function () {

        return {
            require: 'form',
            compile: function (tElem, tAttr) {

                tElem.data('augmented', true);

                return function (scope, elem, attr, form) {
                    elem.on('submit', function ($event) {
                        scope.$broadcast('form:submit', form);

                        if (!form.$valid) {
                            $event.preventDefault();
                        }
                        scope.$apply(function () {
                            scope.submitted = true;
                        });


                    });
                }
            }
        };


  })

3)

вы не хотите использовать функцию директивы ng-change, как показано ниже

  <form  ng-app="myApp"  ng-controller="validateCtrl" name="myForm" novalidate ng-change="submitFun()">
      <p>Email:<br>
        <input type="email" name="email" ng-model="email" required>
        <span ng-show="submitted || myForm.email.$dirty && myForm.email.$invalid">
          <span ng-show="myForm.email.$error.required">Email is required.</span>
          <span ng-show="myForm.email.$error.email">Invalid email address.</span>
          </span>
      </p>
<p>
  <input type="submit">
</p>
</form>

Контроллер SubmitFun() JS:

 var app = angular.module('example', []);
 app.controller('exampleCntl', function($scope) {
 $scope.submitFun = function($event) {
 $scope.submitted = true;
  if (!$scope.myForm.$valid) 
  {
        $event.preventDefault();
   }
  }

});

Ответ 5

Вызов проверки на элемент формы может быть обработан путем запуска события изменения этого элемента:

a) Например: смена триггера на отдельный элемент в форме

$scope.formName.elementName.$$element.change();

b) Пример: событие изменения триггера для каждого из элементов формы, например, на ng-submit, ng-click, ng-blur...

vm.triggerChangeForFormElements = function() {
    // trigger change event for each of form elements
    angular.forEach($scope.formName, function (element, name) {
        if (!name.startsWith('$')) {
            element.$$element.change();
        }
    });
};

c) и еще один способ для этого

    var handdleChange = function(form){
        var formFields = angular.element(form)[0].$$controls;
        angular.forEach(formFields, function(field){
            field.$$element.change();
        });
    };

Ответ 6

Я создал компонент кнопки сохранения, чтобы запускать все валидаторы (асинхронные и синхронизирующие) при отправке и вызывать функцию отправки только в том случае, если все они действительны. Таким образом, вы можете проверить при отправке, даже если входные данные не являются грязными.

https://gist.github.com/adammfrank/9cee444720415740accbe26360b9de23