3

See Fiddle: http://jsfiddle.net/hejado/7bqjqc2w/

I'm trying to form.reset() my form using angular.

HTML:

<div ng-controller="formCtrl">
<form name="resetme" id="resetme">
    <input ng-model="text" type="text" />
    <input file-model="file" type="file" />
    <button type="button" ng-click="resetForm()">reset</button>
</form>
</div>

JS:

.controller('formCtrl', function($scope) {
    $scope.resetForm = function() {
    //$scope.resetme.reset();
    document.getElementById('resetme').reset();
    };
});

Please note: I'm using this kind of form to ajax-upload a file. The page is not refreshing and I don't want to use any reset-buttons. (I'm using one in the fiddle for simplicity.) I want to call the reset-function after the fileupload is finished (via http success).

I'm using

<input type="file" />

so I can't reassign empty values to all my inputs, because file inputs are readonly.

Calling the reset() function on the DOM element works, but I was told talking to the DOM in angular would be evil, so...

I'd like to know, how this would be done the angular way. I tried naming the form and referencing it via $scope.formname but I'm not able to call Web API functions... (commented line)

How can I achieve this?

UPDATE After reading some of the answers, I should make clear, that I am using ngModel and a custom directive fileModel to get a hold of the file-object.

Some of the solutions worked in resetting the value of the input field, but the model is not cleared (neither file, nor text). Custom directives are the answer to that, but this kinda exceeds the scope of this question.

Nico Prediger
  • 43
  • 1
  • 1
  • 7

6 Answers6

4

I wrote about this topic a couple years ago. I don't know if the Angular team has yet implemented a native form reset directive but you can do so yourself. There are a couple caveats to this implementation: it only works for one model (if you need to support more see the followup post) and the issue of when to initialize the original values. Also, I never tested this with file inputs so I am not sure it would work with those.

There was an issue for this but it was closed due to inactivity. :/

var myApp = angular.module('myApp', []);

myApp.controller('MyCtrl', ['$scope',
  function($scope) {
    $scope.myModel = {
      foo: 'Boop',
      bar: 'Beep'
    };
    $scope.myModelCopy = angular.copy($scope.myModel);
  }
]);

myApp.directive('resetDirective', ['$parse',
  function($parse) {
    return function(scope, element, attr) {
      var fn = $parse(attr.resetDirective);
      var masterModel = angular.copy(fn(scope));

      // Error check to see if expression returned a model
      if (!fn.assign) {
        throw Error('Expression is required to be a model: ' + attr.resetDirective);
      }

      element.bind('reset', function(event) {
        scope.$apply(function() {
          fn.assign(scope, angular.copy(masterModel));
          scope.form.$setPristine();
        });

        // TODO: memoize prevention method
        if (event.preventDefault) {
          return event.preventDefault();
        } else {
          return false;
        }
      });
    };
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
  <div ng-controller="MyCtrl">
    <form reset-directive="myModel" name="form">
      <input type="text" ng-model="myModel.foo" />
      <input type="text" ng-model="myModel.bar" />
      <input type="reset" value="Reset" />
      <pre>myModel: {{ myModel | json }}</pre>
      <pre>myModelCopy: {{ myModelCopy | json }}</pre>
      <pre>form pristine: {{ form.$pristine }}</pre>
    </form>
  </div>
</body>
Jason Cust
  • 10,743
  • 2
  • 33
  • 45
0

You can try :

<a href="#" ng-click="resetForm()">reset</a>

$scope.resetForm = function(form) {
  //Even when you use form = {} it does not work
  form.fieldA = null;
  form.fieldB = null;
  ///more fields
}

Or

$scope.resetForm = function(form) {
      //Even when you use form = {} it does not work
      angular.copy({},form);
    }

See Demo

Bhavin Solanki
  • 4,740
  • 3
  • 26
  • 46
0

You'd want to attach ng-model to each of your input fields then null them out via $scope. Either that or make a custom directive

Parris Varney
  • 11,320
  • 12
  • 47
  • 76
  • I saw you `file` type caveat after posting, so you're right using ng-model might be a problem. I think you can still use a custom directive though, you can access the form's DOM via the element parameter and still be doing it "the angular way". I also saw a somewhat related stack thread that might help: http://stackoverflow.com/questions/17922557/angularjs-how-to-check-for-changes-in-file-input-fields – Parris Varney Jul 23 '15 at 12:27
0

I've just had a similar problem with forms not resetting. Here's what I would do:

In your resetform() function, I would include statements that set both of your ng-models in your input to "". For example:

**HTML**
 <input ng-model="text" type="text" />
 <input file-model="file" type="file" />
**JS**
.controller('formCtrl', function($scope) {
    $scope.resetForm = function() {
    $scope.text = "";
    $scope.file = null;
    };
});

Not certain if this will work for file-models but I'm certain it will remove the text. Best of luck!

-1

If you don't want to use ng-model and proper reset type of button you can use this code, however this is not proper angular way to reset the form but it will work

$scope.reset = function(){
    $('form').children('*').each(function(){
      $(this).val('');
    });
  }

Here's the Plunker

blue
  • 932
  • 7
  • 9
  • Yes, it works, but unfortunately it does not clear any ng-models... Add ng-model="text" to the input and {{text}} to the view. Resetting deletes the input, but not the model... – Nico Prediger Jul 24 '15 at 07:53
  • He is not using ng-model he says that't why I posted this solution, otherwise if he will use ng-model then that also need to clear. – blue Jul 27 '15 at 07:01
-3

To reset the form data use following code :

    $scope.resetEmployeeData = function() {

    $scope.employeeCred.userName = '';
    $scope.employeeCred.employeeNo = '';
    $scope.employeeCred.sapNo = '';
    $scope.employeeCred.emailD = '';
    $scope.employeeCred.mobileNo = '';
    **this**.createEmployee.$setPristine();
    **this**.createEmployee.$setUntouched();

};

use this rather than $scope.

Nawrez
  • 3,314
  • 8
  • 28
  • 42