Reputation: 1911
I would like to adjust display of form items such as a button's enabled/disabled attribute by testing the Angular JS pristine setting.
When a click event fires the form's pristine value is changed as I would expect but when I manipulate the scope variable directly the form's pristine setting is not changed even though a control on the form is bound to that variable.
Please see the following JSfiddle:
http://jsfiddle.net/nicholasporter/2h7wT/3/
I would expect that the altering of the boolean value would cause the forms pristine setting to change when a control is bound to a scope variable. Is there a better way to test this? Is there a better way to adjust buttons or other DOM elements when nothing has changed on the form? Thanks in advance for any pointers. Here is the code in case the JSfiddle isn't working.
<div ng-app ng-controller="MyCtrl">
<form novalidate name="myForm">
{{myBool}}
<input type="checkbox" ng-model="myBool" />
<button ng-click="myBool=!myBool">JS set</button>
<div>Form Pristine:{{myForm.$pristine}}</div>
</form>
</div>
<script>
function MyCtrl($scope){
$scope.myBool = false;
}
</script>
Upvotes: 23
Views: 37602
Reputation: 1000
The $pristine
propery of a an input with an ng-model
directive only changes when its ngModelControllers $setViewValue()
method is used, that is through user interaction on the input element or by calling that method yourself.
This is because the pristine state is used to keep track of wether you changed (modified any ng-model
-enabled input elements in) the form. It does not mean that the values in the inputs are equal to the values in the model, they always are updated after every keystroke!
There's no automatic way to reset a form to pristine, you have to decide yourself when to do that by calling form.$setPristine()
.
If you want to reset the pristine information in your example, you have to tell the form to reset itself by binding the button to a function on the scope:
$scope.toggleBool = function() {
$scope.myBool = !$scope.myBool;
$scope.myForm.$setPristine();
}
If you want to have a separate set of values for the form and for an object's original state, you have to clone the object and then use the clone in the form. Otherwise all changes always immediately alter the original object.
You can then determine the state of the form by performing a deep comparison between the original object and it's clone.
UPDATE May '15: This answer is from 2013. ngModelController has gained a significantly richer API in recent versions of Angular (currently 1.4), that offers some mechanisms for managing form state.
Upvotes: 28