Skip to content
This repository has been archived by the owner on Apr 12, 2024. It is now read-only.

Issue #856: add ability to reset a form to its pristine state #1127

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/ng/directive/form.js
Expand Up @@ -5,7 +5,8 @@ var nullFormCtrl = {
$addControl: noop,
$removeControl: noop,
$setValidity: noop,
$setDirty: noop
$setDirty: noop,
$setPristine: noop
};

/**
Expand Down Expand Up @@ -119,6 +120,31 @@ function FormController(element, attrs) {
form.$pristine = false;
};

/**
* @ngdoc function
* @name ng.directive:form.FormController#$setPristine
* @methodOf ng.directive:form.FormController
*
* @description
* Sets the form to its pristine state.
*
* This method can be called to remove the 'ng-dirty' class and set the form to its pristine
* state (ng-pristine class). This method will also propagate to all the controls contained
* in this form.
*
* Setting a form back to a pristine state is often useful when we want to 'reuse' a form after
* saving or resetting it.
*/
form.$setPristine = function () {
element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
form.$dirty = false;
form.$pristine = true;
angular.forEach(form, function(value, key) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no angular, just forEach

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yes!

if (value.$name && value.$setPristine) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you check for $name? anonymous form controls should be reset as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that anonymous form controls are not tracked as part of the form controller. Looked at the $addControl method:

https://github.com/angular/angular.js/blob/master/src/ng/directive/form.js#L64 and the same check for $removeControl:
https://github.com/angular/angular.js/blob/master/src/ng/directive/form.js#L70

If I'm correct then we don't have anonymous controls (inputs and sub-forms) on the FormController level and thus can't reset them to their pristine state. Still individual controls can be reset.

We could relay on the presence of the $setPristine function only but somehow it didn't feel "right". Let me know if you want me to remove this test for the $name property. In any case it won't change the fact that we can't (?) reset anonymous controls from a form level.

@IgorMinar might have missed something here but at least this was reasoning.

value.$setPristine();
}
});
};
}


Expand Down
16 changes: 16 additions & 0 deletions src/ng/directive/input.js
Expand Up @@ -947,6 +947,22 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
parentForm.$setValidity(validationErrorKey, isValid, this);
};

/**
* @ngdoc function
* @name ng.directive:ngModel.NgModelController#$setPristine
* @methodOf ng.directive:ngModel.NgModelController
*
* @description
* Sets the control to its pristine state.
*
* This method can be called to remove the 'ng-dirty' class and set the control to its pristine
* state (ng-pristine class).
*/
this.$setPristine = function () {
this.$dirty = false;
this.$pristine = true;
$element.removeClass(DIRTY_CLASS).addClass(PRISTINE_CLASS);
}

/**
* @ngdoc function
Expand Down
26 changes: 26 additions & 0 deletions test/ng/directive/formSpec.js
Expand Up @@ -327,4 +327,30 @@ describe('form', function() {
expect(doc).toBeDirty();
});
});

describe('set pristine state', function() {

beforeEach(function() {
doc = $compile(
'<form name="form">' +
'<input ng-model="name" name="name" store-model-ctrl/>' +
'</form>')(scope);

scope.$digest();
});

it('should set form and controls to the pristine state', function() {

var form = scope.form, input = doc.find('input').eq(0);

control.$setViewValue('');
scope.$apply();
expect(doc).toBeDirty();

form.$setPristine();
expect(doc).toBePristine();
expect(input).toBePristine();
expect(control.$pristine).toBeTruthy();
});
});
});
12 changes: 12 additions & 0 deletions test/ng/directive/inputSpec.js
Expand Up @@ -117,6 +117,18 @@ describe('NgModelController', function() {
});
});

describe('setPristine', function() {

it('should set control to its pristine state', function() {
ctrl.$setViewValue('edit');
expect(ctrl.$dirty).toBe(true);
expect(ctrl.$pristine).toBe(false);

ctrl.$setPristine();
expect(ctrl.$dirty).toBe(false);
expect(ctrl.$pristine).toBe(true);
});
});

describe('view -> model', function() {

Expand Down