How to set a particular field in a form to dirty in angularjs 1.3

I want to set a field of a particular form as dirty as I am manually changing that value.I have already gone the the SO thread Angular.js programmatically setting a form field to dirty , But no luck.

Here is the sample replica of my issue. Plunk

<html ng-app="sampleApp">

<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0- rc.4/angular.min.js"></script>
 <style type="text/css">
 input.ng-invalid {
  border: 1px solid red;
 }
input.ng-valid {
  border: 1px solid green;
}
input.ng-pristine {
  border-color: #FFFF00;
}
</style>
<script type="text/javascript">
 var sampleApp = angular.module("sampleApp", []);
 sampleApp.controller('sampleCtrl', ['$scope', '$http', '$timeout',
   function($scope, $http, $timeout) {
     $scope.userData = {
       username: "",
     };

     $timeout(function() {
       $scope.userData.username = '$#deepak';
     }, 5000);

   }
 ]);
 sampleApp.directive('myUsername', [
   function() {
     // Runs during compile
     return {

       require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent 
       link: function($scope, iElm, iAttrs, controller) {

         controller.$parsers.unshift(function(value) {
           //allow only alphanumeric characters
           var reg = /^\w+$/;
           var isValidUsername = reg.test(value);
           controller.$setValidity('username', isValidUsername);

           return isValidUsername ? value : undefined;
         });

         controller.$formatters.unshift(function(value) {
           var reg = /^\w+$/;
           var isValidUsername = reg.test(value);

           controller.$setValidity('username', isValidUsername);
          $scop  e.registrationForm.username.$setViewValue($scope.registrationForm.username.$viewValue);
           return value;
         })

       }
     };
   }
 ]);
  </script>
  </head>

 <body ng-controller="sampleCtrl">
  <div ng-show="bShowStatus">
   {{message}}
   <ul ng-repeat="err in errors">
     {{err}}
   </ul>
  </div>
  <form name="registrationForm" ng-submit="submitForm()" novalidate>
    UserName
    <br>
    <input type="text" name="username" ng-model="userData.username" ng-model-options="{updateOn:  'blur'}" my-username>&nbsp;&nbsp;
    <span ng-show="registrationForm.username.$dirty && registrationForm.username.$error.username">
            Invalid Username.
        </span>

 <br>
 <br>
 <input type="submit" value="Submit">
 </form>
</body>

</html>

In the sample I am modifying the username after 5 second (only for the example). At the same time , I want to set the field as dirty and fire the validation and show the error message.

Please help.

Answers:

Answer

Deepak

Here is the plnkr with the solution http://plnkr.co/edit/69Beli?p=preview. Instead of updating the $scope.userData.username directly and bypassing the parser pipeline of 'model to view', use jQuery to update the input field and trigger the 'change' event and use the 'view to model' pipeline provided by Angular.

            $timeout(function(){
              jQuery("[name=username]").val('$#deepak');
              jQuery("[name=username]").trigger('change');
            }, 5000);

Another plnkr http://plnkr.co/edit/Zct92r with $render implemented. This is for 'model to view' pipeline, $render is invoked after $parser and setting the styles based on errors.

    controller.$render = function() {
      console.log('in render');
      iAttrs.$set('value', controller.$viewValue);
      if (controller.$invalid && controller.$viewValue.length !== 0) {
        iElm.css("border", "1px solid red");
      } else if (controller.$viewValue.length === 0) {
        iElm.css("border", "1px solid gold");
      } else {
        iElm.css("border", "1px solid green");
      }
    };

Both solution feels like a hack and $render feels more so. Whatever is set in $render, has to be compensated in $parser and undone.

Answer

Well, it works for me using the $dirty flag discussed in the thread (Angular.js programmatically setting a form field to dirty):

$timeout(function(){
    $scope.userData.username = '$#deepak';
    $scope.registrationForm.username.$dirty = true;
}, 5000);

See working plunker here: http://plnkr.co/edit/ZvX62jJsklPLyw7Q4nlT?p=preview

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.