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

All we need is an easy explanation of the problem, so here it is.

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

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply