最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Do not trigger form.$invalid on first load - Stack Overflow

programmeradmin1浏览0评论

Having such form

    <div ng-controller="FormController as f_ctrl">
    <form ng-submit="f_ctrl.submit()" name="myForm">
    <input type="text" ng-model="f_ctrl.user.username"
            required
            ng-minlength="4"/>
    <input type="text" ng-model="f_ctrl.user.password"/>
    <input type="submit" value="Submit" ng-disabled="myForm.$invalid">
    </form>
</div>

and such controller

    .controller('FormController', [function() {
    var self = this;

    self.submit = function() {
        console.log('User submitted form with ' + self.user.username)
    }
}]);

I have a problem: when page first loads it immediately shows red border on username field, even before I start typing anything. I need to highlight invalid fields only after first submission. Can this be done using form.$invalid ?

Having such form

    <div ng-controller="FormController as f_ctrl">
    <form ng-submit="f_ctrl.submit()" name="myForm">
    <input type="text" ng-model="f_ctrl.user.username"
            required
            ng-minlength="4"/>
    <input type="text" ng-model="f_ctrl.user.password"/>
    <input type="submit" value="Submit" ng-disabled="myForm.$invalid">
    </form>
</div>

and such controller

    .controller('FormController', [function() {
    var self = this;

    self.submit = function() {
        console.log('User submitted form with ' + self.user.username)
    }
}]);

I have a problem: when page first loads it immediately shows red border on username field, even before I start typing anything. I need to highlight invalid fields only after first submission. Can this be done using form.$invalid ?

Share Improve this question asked Aug 5, 2015 at 8:06 Keeps KeepsKeeps Keeps 411 silver badge2 bronze badges 1
  • If it is firefox only problem, angular recently fixed it on master – YOU Commented Aug 5, 2015 at 23:35
Add a ment  | 

3 Answers 3

Reset to default 3

You have to use $pristine for that. It is true when form controller is not changed. so when you change textbox data its es false.

Small example for you.

<div class="form-group" ng-class="{ 'has-error' : userForm.password.$invalid && !userForm.password.$pristine }">
    <input id="passAnime" type="password" name="password" ng-model="user.password" class="form-control input-md" placeholder="Password" tabindex="5" ng-maxlength="25" ng-minlength="6" required>

    <span ng-show="userForm.password.$dirty && userForm.password.$invalid">
        <p ng-show="userForm.password.$error.required" class="error-messages">
             Your password is required.
        </p>
        <p ng-show="userForm.password.$error.minlength" class="error-messages">
            Your password is too short. Minimum 6 chars.
        </p>
        <p ng-show="userForm.password.$error.maxlength" class="error-messages">
            Your password is too long. Maximum 25 chars. 
        </p>
    </span>
</div>

Angular has helpers that tell you if the form (or form field) is $dirty (user has typed something) or if the form is $touched (the blur event has been triggered on the input). See this demo.

I need to highlight invalid fields only after first submission.

Unfortunately, Angular doesn't support that. But you could implement it yourself rather easily:

Controller

function FormController() {
  var vm = this;
  vm.submitAttempted = false;
  vm.submit = function(isValid) {
    if (isValid) {
      // do stuff
    }
    else {
      vm.submitAttempted = true;
    }
  };
}

HTML

<div ng-app='app'>
  <div ng-controller='FormController as vm'>
    <form name='fooForm' ng-submit='vm.submit(fooForm.$valid)' novalidate>
      <label>Username</label>
      <input 
        name='username' 
        type='text' 
        ng-model='vm.user.username'
        required
        ng-minlength='4'
        ng-class="{'invalid': vm.submitAttempted && fooForm.username.$invalid}">
      <br /><br />
      <button type='submit'>Submit</button>
    </form>
  </div>
</div>

CSS

.invalid {
  border-color: red;
}

Demo


I have a problem: when page first loads it immediately shows red border on username field, even before I start typing anything.

That's probably because you have the following CSS class:

.ng-invalid {
  border-color: red;
}

Angular will always apply the ng-invalid class to fields that are invalid, and there's nothing you could do about that. So if you don't always want invalid fields to have a red border, you can't use that class and you should do it in a way similar to what I proposed above.


Also, check out ngMessages.

You can disable the default styling on the input field that is adding the red border by default, by adding the following CSS:

input:required {
    -moz-box-shadow: none;
    box-shadow: none;
}

Then if you want to highlight the field when the form is submitted, you will need to ensure that the form and form fields have relevant name attributes. Doing this will allow you to check if the field is valid or not and apply a class to your text field when it is invalid:

<input type="text" name="username" ng-class="{ 'invalid-field' : f_ctrl.myForm.username.$invalid && !f_ctrl.myForm.username.$pristine }" required />

f_ctrl.myForm and f_ctrl.myform.username will have additional properties that you can use/check to determine if the form or fields are invalid or not, or if they have been modified at any point (e.g. f_ctrl.myform.username.$dirty). You should be able to view these properties on your page by adding the follow HTML:

<div>
    <pre>{{f_ctrl.myForm | json}}</pre>
</div>

Or, you could output self.myForm to the console from your controller to view it's properties

console.log(self.myForm);
发布评论

评论列表(0)

  1. 暂无评论