Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Angular JS form.$pristine not change with direct JS manipulation

Tags:

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> 
like image 648
likestoski Avatar asked Feb 12 '13 17:02

likestoski


People also ask

What is pristine angular form?

pristine: This property returns true if the element's contents have not been changed. dirty: This property returns true if the element's contents have been changed. untouched: This property returns true if the user has not visited the element.

Which directive responsible for use forms in Angular JS?

ng-form directive allows us to use a form in AngularJs.

What is the difference between Ng dirty and Ng-pristine in angular?

CSS Classes ng-untouched The field has not been touched yet. ng-touched The field has been touched. ng-pristine The field has not been modified yet. ng-dirty The field has been modified.

How do you make a pristine false form?

Using $setPristine will set the $pristine property of the form to true and $dirty to false. $setDirty will do the contrary.


1 Answers

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.

like image 188
Jan Avatar answered Oct 21 '22 15:10

Jan