0

I'm using an AngularJS form for a contact form and would like to reset the form on successful submission. I've found plenty of examples of how to reset an AngularJS Form and have that working, however, I've been unable to figure out a way to successfully reset the form on submission. My reset() function clears the form fields and appears to set the state of the form back to pristine when called on submit, however, the messages that should only be shown when a field is invalid are still displayed.

Here's my controller code with the function...

function ContactCtrl() {
  var vm = this;
  vm.reset = reset;
  vm.submit = submit;


  function reset(form) {
    if (form) {
      vm.name = undefined;
      vm.email = undefined;
      form.$setValidity();
      form.$setPristine();
      form.$setUntouched();
    }
  }

  function submit(form) {
    if (form) {
      vm.reset(form);
    }
  }
}

The full code can be found below or on Plunker

angular
  .module('plunker', [])
  .controller('ContactCtrl', ContactCtrl);

function ContactCtrl() {
  var vm = this;
  vm.reset = reset;
  vm.submit = submit;


  function reset(form) {
    if (form) {
      vm.name = undefined;
      vm.email = undefined;
      form.$setValidity();
      form.$setPristine();
      form.$setUntouched();
    }
  }

  function submit(form) {
    if (form) {
      vm.reset(form);
    }
  }
}
<!DOCTYPE html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8" />
  <title>AngularJS Plunker</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <link rel="stylesheet" href="style.css" />
  <script data-require="[email protected]" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="ContactCtrl as contact">
  <form name="form" novalidate>
    Name:
    <input type="text" ng-model="contact.name" name="uName" required="" />
    <br />
    <div ng-show="form.$submitted || form.uName.$touched">
      <div ng-show="form.uName.$error.required">Tell us your name.</div>
    </div>

    E-mail:
    <input type="email" ng-model="contact.email" name="uEmail" required="" />
    <br />
    <div ng-show="form.$submitted || form.uEmail.$touched">
      <span ng-show="form.uEmail.$error.required">Tell us your email.</span>
      <span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
    </div>

    <input type="button" ng-click="contact.reset(form)" value="Reset" />
    <input type="submit" ng-click="contact.submit(form)" value="Submit" />
  </form>
  <pre>
    FORM:
    form.$pristine = {{form.$pristine}}
    form.$dirty = {{form.$dirty}}
    form.$submitted = {{form.$submitted}}
    
    NAME:
    form.uName.$pristine = {{form.uName.$pristine}}
    form.uName.$dirty = {{form.uName.$dirty}}
    form.uName.$valid = {{form.uName.$valid}}
    form.uName.$invalid = {{form.uName.$invalid}}
    
    EMAIL:
    form.uEmail.$pristine = {{form.uEmail.$pristine}}
    form.uEmail.$dirty = {{form.uEmail.$dirty}}
    form.uEmail.$valid = {{form.uEmail.$valid}}
    form.uEmail.$invalid = {{form.uEmail.$invalid}}
    
  </pre>
</body>

</html>

2
  • 2
    That's probably because after you reset the form, the blur event on the field is going to be fired and triggers the form validation. Commented Feb 9, 2016 at 20:47
  • That's what I noticed as well. If your form is valid, it works correctly, however; if there's an error in the form, the validation runs and doesn't trigger the ngClick. Commented Feb 9, 2016 at 20:48

3 Answers 3

1

you could put the function you want to run on-submit inside of an ng-submit directive, this appears to get executed the same as the reset button:

<form name="form" ng-submit="contact.submit(form)">
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! That was the solution for me.
1

Try the following, adding ng-submit

<form name="form" novalidate ng-submit="contact.submit(form)">

It worked for me.

Your button should look like this now

 <input type="submit"  value="Submit" />

hope this helps.

Comments

1

I also found that if you want to still use the form submit instead of ng-submit event, you need to wrap your form clearing code in a $timeout function. This forces the code you stick inside the $timeout to execute 'synchronously' to any other event actions (in this case the form submit).

Modified Plunkr seen here

angular
  .module('plunker', [])
  .controller('ContactCtrl', ['$scope','$timeout', ContactCtrl]);

function ContactCtrl($scope, $timeout) {
  var vm = this;
  vm.reset = reset;
  vm.submit = submit;
  vm.resetMe = resetMe;


  function reset($event, form) {
    if ($scope.form) {
      $timeout(function(){
        vm.name = undefined;
        vm.email = undefined;
        $scope.form.$setValidity();
        $scope.form.$setPristine();
        $scope.form.$setUntouched();        
      });
    }
  }

  function submit(form) {
    if (form) {
      vm.reset(form);
    }
  }

  function resetMe(){
    console.log($scope);
    debugger;
    $scope.form.$setPristine();
  }
}

1 Comment

Nice! That makes sense. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.