Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 1.2: Is it possible to exclude an input on form dirty checking?

In the example beneath, is it possible to ignore the dirty state of the dropdown list? Now it get's dirty if the user changes the selected person. But I don't care if this field is dirty in my form validation.

function TestingCtrl($scope) {
  $scope.company = '';
  $scope.persons = [{
    name: 'Alice'
  }, {
    name: 'Bob'
  }];


  $scope.selectedPerson = $scope.persons[0];

  $scope.checkForm = function() {
    if ($scope.personForm.$dirty) {
      alert('Form is dirty');
    } else {
      alert('Form is clean');
    }
  }

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>


<div ng-app>

  <div ng-controller="TestingCtrl">

    <form name="personForm" novalidate>
      Company:
      <input type="text" ng-model="company" required>
      <br>Persons:
      <select ng-options="p.name for p in persons" ng-model="selectedPerson"></select>

    </form>

    <br>
    <button ng-click="checkForm()">Check if dirty</button>

  </div>

</div>
like image 262
HoffZ Avatar asked Feb 25 '15 14:02

HoffZ


People also ask

What's the difference between dirty touched and pristine in a form element?

$pristine / $dirty tells you whether the user actually changed anything, while $touched / $untouched tells you whether the user has merely been there/visited.

What is Angular dirty checking?

Angular Dirty Checking mechanism workflow. Dirty checking is a simple process that boils down to a very basic concept: It checks whether a value has changed that hasn't yet been synchronized across the app. Our Angular app keeps track of the values of the current watches.

What is the difference between Ng dirty and Ng pristine in Angular?

The main difference between both of them is that ng-dirty is used to tell that the input field is modified by the user and the ng-pristine is used to tell us that the field is untouched by the user.

What is dirty in form validation?

Form State and Input State $touched The field has been touched. $pristine The field has not been modified yet. $dirty The field has been modified. $invalid The field content is not valid.


1 Answers

I don't know if you have any other input elements in your form. But in your case you could explicitely check if the company input is dirty:

function TestingCtrl($scope) {
  $scope.company = '';
  $scope.persons = [{
    name: 'Alice'
  }, {
    name: 'Bob'
  }];


  $scope.selectedPerson = $scope.persons[0];

  $scope.checkForm = function() {
    var isDirty = false;

    angular.forEach($scope.personForm, function (value, key) {
        // Input element
        if (value.hasOwnProperty('$modelValue') && value.$name!='person') {
            isDirty = isDirty || value.$dirty;
        }
    });
    if (isDirty ) {
      alert('Form is dirty');
    } else {
      alert('Form is clean');
    }
  }

}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>


<div ng-app>

  <div ng-controller="TestingCtrl">

    <form name="personForm" novalidate>
      Company:
      <input name="company" type="text" ng-model="company" required>
      <br>Persons:
      <select name="person" ng-options="p.name for p in persons" ng-model="selectedPerson"></select>

    </form>

    <br>
    <button ng-click="checkForm()">Check if dirty</button>

  </div>

</div>

UPDATE I have updated my solution, now you can exclude specific input fields. However each input field has to have the attribute name set

UPDATE II

A much cleaner solution would be to use a directive which prevents the form from setting the state to dirty if the value of a specific input is set. Here you have an example:

angular.module('myApp', []).directive('ignoreDirty', [function() {
    return {
    restrict: 'A',
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$pristine = false;
    }
  }
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
  <form name="test">
    Watching dirty: <input ng-model="name" /><br />
    Ignoring dirty: <select ng-model="gender" ignore-dirty>
      <option>male</option>
      <option>female</option>
    </select><br />
    dirty: {{test.$dirty}}
  </form>
</div>
like image 126
boindiil Avatar answered Sep 18 '22 13:09

boindiil