How do I reset a form including removing all valid

2019-01-22 12:27发布

I have an Angular form. The fields are validated using the ng-pattern attribute. I also have a reset button. I'm using the Ui.Utils Event Binder to handle the reset event like so:

<form name="searchForm" id="searchForm" ui-event="{reset: 'reset(searchForm)'}" ng-submit="search()">
  <div>
    <label>
      Area Code
      <input type="tel" name="areaCode" ng-model="areaCode" ng-pattern="/^([0-9]{3})?$/">
    </label>

    <div ng-messages="searchForm.areaCode.$error">
      <div class="error" ng-message="pattern">The area code must be three digits</div>
    </div>
  </div>

  <div>
    <label>
      Phone Number
      <input type="tel" name="phoneNumber" ng-model="phoneNumber" ng-pattern="/^([0-9]{7})?$/">
    </label>

    <div ng-messages="searchForm.phoneNumber.$error">
      <div class="error" ng-message="pattern">The phone number must be seven digits</div>
    </div>
  </div>

  <br>
  <div>
    <button type="reset">Reset</button>
    <button type="submit" ng-disabled="searchForm.$invalid">Search</button>
  </div>
</form>

As you can see, when the form is reset it calls the reset method on the $scope. Here's what the entire controller looks like:

angular.module('app').controller('mainController', function($scope) {
    $scope.resetCount = 0;

    $scope.reset = function(form) {
        form.$setPristine();
        form.$setUntouched();
        $scope.resetCount++;
    };

    $scope.search = function() {
        alert('Searching');
    };
});

I'm calling form.$setPristine() and form.$setUntouched, following the advice from another question here on Stack Overflow. The only reason I added the counter was to prove that the code is being called (which it is).

The problem is that even after reseting the form, the validation messages don't go away. You can see the full code on Plunker. Here's a screenshot showing that the errors don't go away:

Validation Errors

10条回答
孤傲高冷的网名
2楼-- · 2019-01-22 13:29

further to @battmanz 's answer, but without using any ES6 syntax to support older browsers.

 $scope.resetForm = function (form) {

            try {
                var controlNames = Object.keys(form).filter(function (key) { return key.indexOf('$') !== 0 });

                console.log(controlNames);
                for (var x = 0; x < controlNames.length; x++) {
                    form[controlNames[x]].$setViewValue(undefined);
                }

                form.$setPristine();
                form.$setUntouched();
            } catch (e) {                
                console.log('Error in Reset');
                console.log(e);
            }

        };
查看更多
Deceive 欺骗
3楼-- · 2019-01-22 13:30
      $scope.search = {areaCode: xxxx, phoneNumber: yyyy}

Structure all models in your form in one place like above, so you can clear it like this:

      $scope.search = angular.copy({});

After that you can just call this for reset the validation:

      $scope.search_form.$setPristine();
      $scope.search_form.$setUntouched();
      $scope.search_form.$rollbackViewValue();
查看更多
我命由我不由天
4楼-- · 2019-01-22 13:31

There doesn't seem to be an easy way to reset the $errors in angular. The best way would probably be to reload the current page to start with a new form. Alternatively you have to remove all $error manually with this script:

form.$setPristine(true);
form.$setUntouched(true);

// iterate over all from properties
angular.forEach(form, function(ctrl, name) {
  // ignore angular fields and functions
  if (name.indexOf('$') != 0) {
    // iterate over all $errors for each field        
    angular.forEach(ctrl.$error, function(value, name) {
      // reset validity
      ctrl.$setValidity(name, null);
    });
  }
});
$scope.resetCount++; 
查看更多
叛逆
5楼-- · 2019-01-22 13:33

So none of the answers were completely working for me. Esp, clearing the view value, so I combined all the answers clearing view value, clearing errors and clearing the selection with j query(provided the fields are input and name same as model name)

 var modelNames = Object.keys($scope.form).filter(key => key.indexOf('$') !== 0);
                    modelNames.forEach(function(name){
                        var model = $scope.form[name];
                        model.$setViewValue(undefined);
                        jq('input[name='+name+']').val('');
                        angular.forEach(model.$error, function(value, name) {
                          // reset validity
                          model.$setValidity(name, null);
                        });
                    });
                    $scope.form.$setPristine();
                    $scope.form.$setUntouched();
查看更多
登录 后发表回答