AngularJS Form Reset Directive Concept Proposal
A directive that supports the native reset button type in AngularJS forms with multiple models.
HTML
<script src="http://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<div ng-controller="MyCtrl">
<form ng-reset name="form">
<input type="text" ng-model="myModel.foo" />
<input type="text" ng-model="myOtherModel.foo" />
<input type="reset" value="Reset" />
<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('ngReset', function myReset($timeout) {
var preventDefault = (function () {
if (angular.isObject(Event)) {
return function (event) {
return event.preventDefault();
};
}
else {
return function (event) {
return (event.returnValue = false);
};
}
})();
return {
restrict: 'A',
require: 'form',
link: {
pre: function ngResetLink(scope, element, attrs, formCtrl) {
var addControl = formCtrl.$addControl,
removeControl = formCtrl.$removeControl,
masters = [],
timeouts = [];
// Hack to capture ngModel registration to the form controller
// without access to the form controller's internal controls array
formCtrl.$addControl = function (ngModel) {
masters.push(ngModel);
// Need to wait for initial expressions to be evaluated during
// compile/link phase to store initial model value
timeouts.push($timeout(function () {
ngModel._origViewValue = ngModel.$viewValue;
}), false);
addControl.apply(this, arguments);
};
formCtrl.$removeControl = function (ngModel) {
var index = masters.indexOf(ngModel);
if (index >= 0) {
// Cleanup ngModel
delete ngModel._origViewValue;
masters.splice(index, 1);
}
removeControl.apply(this, arguments);
};
element.on('reset', function (event) {
angular.forEach(masters, function (ngModel) {
ngModel.$setViewValue(ngModel._origViewValue);
ngModel.$render();
});
scope.$apply(function () {
formCtrl.$setPristine();
});
preventDefault(event);
...