I have an ng form on a page. Inside the form I have several controls which need to display a save dialog when the form is dirty, ie form.$dirty = true. However there are some navigation controls in the form I don't want to dirty the form. Assume I can't move the control out of the form.
see: http://plnkr.co/edit/bfig4B
How do I make the select box not dirty the form?
Here's a version of @acacia's answer using a directive and not using $timeout. This will keep your controllers cleaner.
.directive('noDirtyCheck', function() {
// Interacting with input elements having this directive won't cause the
// form to be marked dirty.
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
ctrl.$pristine = false;
}
}
});
Then use it in your form like so:
<input type="text" name="foo" ng-model="x.foo" no-dirty-check>
I used @overthink's solution, but ran into the problem mentioned by @dmitankin. However, I didn't want to attach a handler to the focus event. So instead, I endeavored to override the $pristine property itself and force it to return false always. I ended up using Object.defineProperty which is not supported in IE8 and below. There are workarounds to do this in those legacy browsers, but I didn't need them, so they are not part of my solution below:
(function () {
angular
.module("myapp")
.directive("noDirtyCheck", noDirtyCheck);
function noDirtyCheck() {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
var alwaysFalse = {
get: function () { return false; },
set: function () { }
};
Object.defineProperty(ctrl, '$pristine', alwaysFalse);
Object.defineProperty(ctrl, '$dirty', alwaysFalse);
}
};
}
})();
I am also overriding $dirty so it can't be set as dirty either.
Setting the $pristine property to false, only when initializing, works until you call $setPristine() on the form. Then your control has its $pristine back to true and changing the input's value would make your form dirty. To avoid that, set the $pristine on focus:
link: function(scope, elm, attrs, ctrl) {
elm.focus(function () {
ctrl.$pristine = false;
});
}
Angular only sets the form dirty if the control is pristine. So the trick here is to set $pristine on the control to false. You can do it in a timeout in the controller.
see: http://plnkr.co/edit/by3qTM
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With