AngularJS Form Reset Directive (Multiple Models)
A directive that supports the native reset button type in AngularJS forms with multiple models.
HTML
<div ng-controller="MyCtrl">
<form reset-directive="myModel myOtherModel" name="form">
<input type="text" ng-model="myModel.foo" />
<input type="text" ng-model="myOtherModel.foo" />
<input type="reset" value="eset" />
<pre>myModel: {{ myModel | json }}</pre>
<pre>myOtherModel: {{ myOtherModel | json }}</pre>
<pre>form pristine: {{ form.$pristine }}</pre>
</form>
</div>
JavaScript
var myApp = angular.module( 'myApp', [] );
myApp.controller( 'MyCtrl', [ '$scope', function ( $scope ) {
$scope.myModel = { foo: 'Boop' };
$scope.myOtherModel = { foo: 'Beep' };
}]);
myApp.directive( 'resetDirective', [ '$parse', function ( $parse ) {
return function( scope, element, attr ) {
var fns = map( attr.resetDirective.split( /(?:,? |,)/ ), function ( model ) {
var fn = $parse( model );
// Error check to see if expression returned a model
if ( !fn.assign ) {
throw Error( 'Expression is required to be a model: ' + model );
}
return fn;
});
var masterModels = map( fns, function ( fn ) {
return angular.copy( fn( scope ) );
});
element.bind( 'reset', function ( event ) {
scope.$apply( function () {
fns.forEach( function ( fn, i ) {
fn.assign( scope, angular.copy( masterModels[ i ] ) );
});
scope.form.$setPristine();
});
// TODO: memoize prevention method
if ( event.preventDefault ) {
return event.preventDefault();
}
else {
return false;
}
});
};
}]);
function map( obj, iterator, context ) {
var results = [];
angular.forEach( obj, function( value, index, list ) {
results.push(
iterator.call( context, value, index, list )
);
});
return results;
}