AngularJS: How to set one input value from another and get validated as if it were entered by the user?

I am using angular 1.3.0rc2 and I am trying to have an input field, when blurred, set another input field as if it was entered by the user.

If there is only a synchronous validator in the input I'm trying to set, and there are no debounce or async validators, things always work as expected when I do something like:

myForm.username.$setViewValue('some value');
myForm.username.$render();

      

However, things don't seem to work as expected when either an asynchronous validator or debounce exists on the input I'm trying to set, and when the input I'm trying to set is in a state that is currently invalid.

I've created the following plunkr to showcase my troubles. Try setting it to "Full Name" and see what happens to the "Name" field and I also want to set to blur the "Full Name" field. When the Username field is in an invalid state, changing the fully qualified name value and then removing focus from the field does not update the username as I expected.

http://plnkr.co/edit/h1hvf79W8ovqAlNLpBvS

So my question is, how can I set one input field from another in such a way that it works reliably and acts as if the user himself had entered this new input (so it runs through validators and updates the model value accordingly )?

+3


source to share


2 answers


Try try it, it should adjust the username when you blur the full name.

Plunkr

ngModel

Html



Full Name:
<input name="fullName" ng-model="fullName" test-validator change-field="username" />
User Name:
<input name="username" ng-model="username" required />

      

Js

angular.module("testApp",[]).controller("testCtrl", function($scope) {  


}).directive('testValidator', ['$sce', function ($sce) {
  return {
    restrict: 'A',
    require: '?ngModel',
    link: function (scope, element, attrs, ngModel) {
      if(!ngModel) return;

      element.on('blur', function () {
        scope.$apply(read);
      });

      function read() {
        if(attrs.changeField) {
          var field = attrs.changeField;
          scope.myForm[field].$setViewValue(element.val());
          scope.myForm[field].$render();
        }
      }
    }
  }
}])

      

0


source


OK. So the main problem we want to solve is that if the user sets an input that turns out to be invalid, it causes the underlying model's value to be set to undefined, whereas programmatically setting the input to an invalid state doesn't.

It was inconsistent and so I was trying to find a way around it. It turns out that the resolution is not as straight forward as we would like (see https://github.com/angular/angular.js/issues/9295 )

However, instead, a reverse solution was proposed, which involves using ngModelOptions

on the attached form (or on the input, but more complex), with the "allowInvalid" condition equal to true. This means that invalid values ​​will still be tuned to the model, not that the model value will be cleared in this case.

Given that the model is always set regardless of reality, I can go back to a simpler way to programmatically set one form field to another - just set the base value of the model and behave identically if the user set the value himself :)



plunkr demo with re-async validator on second input:

http://plnkr.co/edit/lkDN4qLbbkN79EmRrxsY?p=preview

see how the model ends up the same regardless of whether the second input is set manually or the first input is set regardless of the validity and sue of the asynchronous action authentication, as desired :)

0


source







All Articles