Using $dirty in angularjs in order to check whenever a form is being edited
Asked Answered
T

1

24

I was trying to check whenever my form is being edited by writing some fields of it. I read $dirty should work for that task but I can't figure out what I'm missing here:

<!DOCTYPE html>
<html lang="en">
<script src= "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="formCtrl">
  <form name = "myForm" novalidate>
    First Name:<br>
    <input type="text" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" ng-model="user.lastName">
    <br><br>
    <button ng-click="reset()">RESET</button>
  </form>
  <p> is Form dirty? {{isDirty}}<p>
  <p>form = {{user }}</p>
  <p>master = {{master}}</p>
</div>

<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
    $scope.master = {firstName:"John", lastName:"Doe"};
    $scope.reset = function() {
        $scope.user = angular.copy($scope.master);
    };
    $scope.reset();
    $scope.isDirty = $scope.myForm.$dirty;
});
</script>

</body>
</html>

I'm trying to make the flag isDirty to true whenever the user modifies the form. Thanks

Titanium answered 7/5, 2015 at 8:45 Comment(1)
It's worth noting that an edit and undo of text on the form will result in $dirty being true even though the current and former values are the same. If you want to determine whether there are unsaved changes then you should compare the original to the current.Corinthian
N
37

You are missing name attributes in your form fields which are not enabling form validation for those field. You need to add unique name for each field so that it will get add those field in myForm object

Markup

  <form name="myForm" novalidate>
    First Name:<br>
    <input type="text" name="firstName" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" name="lastName" ng-model="user.lastName">
    <br><br>
    <button ng-click="reset()">RESET</button>
  </form>

Also you are accessing myForm object which is nothing but form object, I won't be available until DOM get rendered, $scope.myForm will be simply undefined at the time of controller initilization, If you really want to access $scope.myForm from controller then you need to put that code in $timeout that will run $timeout function code in next digest cycle.

  $timeout(function(){
    $scope.isDirty = $scope.myForm.$dirty;
  });

Update

There is no need to maintain a separate isDirty flag (this would require to change the separate isDirty flag to reflect any changes in myForm.$dirty flag.) Instead I suggest you use $scope.myForm.$dirty directly as a flag. So use the expression myForm.$dirty, and this flag will change as form gets dirty.

Working Plunkr

Neighbor answered 7/5, 2015 at 8:48 Comment(5)
I just tried to modify as you suggested adding the name attributes but its not working. I keep getting the same error: --> TypeError: Cannot read property '$dirty' of undefinedTitanium
thanks for the Plunkr but , I have just tried it and can only see the false value of the isDirty variable , I wish it becomes true as soon as the user starts to modify some field of the form, is there a way to achieve that?Titanium
@Titanium your html would be simply <p> is Form dirty? {{myForm.$dirty}}<p> no need of extra variableNeighbor
@PankajParkar This is nice, but how can I use javascrcipt/angular to always watch the value of myForm.$dirty in your Plunkr? In your Plunkr I just edited this ` $timeout(function(){ $scope.isDirty = $scope.myForm.$dirty; alert($scope.isDirty); });` but works only the first time the page loads. When I edit the form I get nothing. ThanksReiss
Can also check $dirty on the individual "form controls"; i.e. an input added of the form. <p> individual form control dirty: {{ myForm.firstName.$dirty }} </p>Boom

© 2022 - 2024 — McMap. All rights reserved.