首页 文章

在angularjs中显示提交验证错误消息

提问于
浏览
68

我有一个表单,如果点击提交需要显示验证错误消息 .

这是一个工作plunker

<form name="frmRegister" ng-submit="register();" novalidate>
      <div>
        <input placeholder="First Name" name="first_name" type="text" ng-model="user.firstName" required />
        <span ng-show="frmRegister.first_name.$dirty && frmRegister.first_name.$error.required">First Name is required</span>
      </div>
      <div>
        <input placeholder="Last Name" name="last_name" type="text" ng-model="user.lastName" required />
        <span ng-show="frmRegister.last_name.$dirty && frmRegister.last_name.$error.required">Last Name is required</span>
      </div>
      <div>
        <input placeholder="Email" name="email" type="email" ng-model="user.email" required />
        <span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.required">Email is required.</span>
        <span ng-show="frmRegister.email.$dirty && frmRegister.email.$error.email">Invalid Email address.</span>
      </div>
      <input type="submit" value="Save" />
      <span ng-show="registered">YOU ARE NOW REGISTERED USER</span>
 </form>

当用户开始进行更改时,验证通常正常 . 但它没有显示任何错误消息如果点击提交而没有输入任何内容 .

有没有想过要实现这个目标?或者以其他方式,当单击“提交”按钮时,如何使每个输入字段$ dirty

13 回答

  • 101

    我找到了这个小提琴http://jsfiddle.net/thomporter/ANxmv/2/,它做了一个很好的技巧来引起控制验证 .

    基本上它声明了一个范围成员 submitted ,并在您单击提交时将其设置为true . 模型错误绑定使用此额外表达式来显示错误消息

    submitted && form.email.$error.required
    

    UPDATE

    正如在@Hafez's comment中指出的那样(给他一些赞成!),Angular 1.3+ solution简单地说:

    form.$submitted && form.email.$error.required
    
  • 1

    由于我使用的是Bootstrap 3,我使用了一个指令:(见plunkr

    var ValidSubmit = ['$parse', function ($parse) {
            return {
                compile: function compile(tElement, tAttrs, transclude) {
                    return {
                        post: function postLink(scope, element, iAttrs, controller) {
                            var form = element.controller('form');
                            form.$submitted = false;
                            var fn = $parse(iAttrs.validSubmit);
                            element.on('submit', function(event) {
                                scope.$apply(function() {
                                    element.addClass('ng-submitted');
                                    form.$submitted = true;
                                    if(form.$valid) {
                                        fn(scope, {$event:event});
                                    }
                                });
                            });
                            scope.$watch(function() { return form.$valid}, function(isValid) {
                                if(form.$submitted == false) return;
                                if(isValid) {
                                    element.removeClass('has-error').addClass('has-success');
                                } else {
                                    element.removeClass('has-success');
                                    element.addClass('has-error');
                                }
                            });
                        }
                    }
                }
            }
        }]
    
        app.directive('validSubmit', ValidSubmit);
    

    然后在我的HTML中:

    <form class="form-horizontal" role="form" name="form" novalidate valid-submit="connect()">
      <div class="form-group">
        <div class="input-group col col-sm-11 col-sm-offset-1">
          <span class="input-group-addon input-large"><i class="glyphicon glyphicon-envelope"></i></span>
          <input class="input-large form-control" type="email" id="email" placeholder="Email" name="email" ng-model="email" required="required">
        </div>
        <p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.required">please enter your email</p>
        <p class="col-sm-offset-3 help-block error" ng-show="form.$submitted && form.email.$error.email">please enter a valid email</p>
      </div>
    </form>
    

    UPDATED

    在我的最新项目中,我使用 Ionic 所以我有以下内容,它自动将 .valid.invalid 放在 input-item 上:

    .directive('input', ['$timeout', function ($timeout) {
      function findParent(element, selector) {
        selector = selector || 'item';
        var parent = element.parent();
        while (parent && parent.length) {
          parent = angular.element(parent);
          if (parent.hasClass(selector)) {
            break;
          }
          parent = parent && parent.parent && parent.parent();
        }
        return parent;
      }
    
      return {
        restrict: 'E',
        require: ['?^ngModel', '^form'],
        priority: 1,
        link: function (scope, element, attrs, ctrls) {
          var ngModelCtrl = ctrls[0];
          var form = ctrls[1];
    
          if (!ngModelCtrl || form.$name !== 'form' || attrs.type === 'radio' || attrs.type === 'checkbox') {
            return;
          }
    
          function setValidClass() {
            var parent = findParent(element);
            if (parent && parent.toggleClass) {
              parent.addClass('validated');
              parent.toggleClass('valid', ngModelCtrl.$valid && (ngModelCtrl.$dirty || form.$submitted));
              parent.toggleClass('invalid', ngModelCtrl.$invalid && (ngModelCtrl.$dirty || form.$submitted));
              $timeout(angular.noop);
            }
          }
    
          scope.$watch(function () {
            return form.$submitted;
          }, function (b, a) {
            setValidClass();
          });
    
    
          var before = void 0;
          var update = function () {
            before = element.val().trim();
            ngModelCtrl.$setViewValue(before);
            ngModelCtrl.$render();
            setValidClass();
          };
          element
            .on('focus', function (e) {
              if (ngModelCtrl.$pristine) {
                element.removeClass('$blurred');
              }
    
            })
            .on('blur', function (e) {
              if (ngModelCtrl.$dirty) {
                setValidClass();
                element.addClass('$blurred');
              }
            }).on('change', function (e) {
              if (form.$submitted || element.hasClass('$blurred')) {
                setValidClass();
              }
            }).on('paste', function (e) {
              if (form.$submitted || element.hasClass('$blurred')) {
                setValidClass();
              }
            })
          ;
    
        }
      };
    }])
    

    然后在HTML中:

    <form name='form' novalidate="novalidate" ng-submit="auth.signin(form, vm)">
              <label class="item item-input item-floating-label">
                <span class="input-label">Email</span>
                <input type="email" placeholder="Email" ng-model="vm.email" autofocus="true" required
                  >
              </label>
              <button ng-if="!posting" type="submit" class="item button-block item-balanced item-icon-right  call-to-action">Login<i class="icon ion-chevron-right"></i>
              </button>
    

    并在控制器中:

    self.signin = function (form, data) {
        if (!form.$valid) return;
    
        Authentication.emailLogin(data)
        //...
    

    所以,现在,在CSS中,您可以执行以下操作:

    .item.valid::before{
        float: right;
        font-family: "Ionicons";
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-transform: none;
        text-rendering: auto;
        line-height: 1;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        color: #66cc33;
        margin-right: 8px;
        font-size: 24px;
        content: "\f122";
    }
    
    .item.invalid::before{
        float: right;
        font-family: "Ionicons";
        font-style: normal;
        font-weight: normal;
        font-variant: normal;
        text-transform: none;
        text-rendering: auto;
        line-height: 1;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        color: #ef4e3a;
        margin-right: 8px;
        font-size: 24px;
        content: "\f12a";
    
    /*
        border-left: solid 2px #ef4e3a !important;
        border-right: solid 2px #ef4e3a !important;
    */
    }
    

    MUCH SIMPLER!

  • 0

    我也有同样的问题,我通过添加一个ng-submit来解决问题,该设置将变量设置为true .

    <form name="form" ng-submit="submitted = true" novalidate>
    <div>
        <span ng-if="submitted && form.email.$error.email">invalid email address</span> 
        <span ng-if="submitted && form.email.$error.required">required</span>
        <label>email</label>
        <input type="email" name="email" ng-model="user.email" required>
    </div>
    
    <div>
        <span ng-if="submitted && form.name.$error.required">required</span>
        <label>name</label>
        <input type="text" name="name" ng-model="user.name" required>
    </div>
    
    <button ng-click="form.$valid && save(user)">Save</button>
    </form>
    

    我喜欢使用$ submit的想法,我想我要将Angular升级到1.3;)

  • 2

    我可以想出两种方法来实现它 .

    第一个是删除 novalidate 以启用浏览器的验证 .

    其次,当表单无效时,您可以禁用 save 按钮

    <input ng-disabled="!frmRegister.$valid" type="submit" value="Save" />
    

    希望能帮助到你 .

  • 0

    我的解决方案有bootstrap 3

    http://jsfiddle.net/rimian/epxrbzn9/

    <form class="form" name="form" ng-app novalidate>
      <div class="form-group">
        <input name="first_name"
              type="text"
              class="form-control"
              ng-model="first_name"
              placeholder="First Name"
              required />
      </div>
      <div class="form-group">
        <input name="last_name"
              type="text"
              class="form-control"
              ng-model="last_name"
              placeholder="Last Name"
              required />
      </div>
    
      <button
        type="submit"
        class="btn btn-primary btn-large"
        ng-click="submitted=true">
          Submit
      </button>
    
    <div ng-show="submitted && form.$invalid" class="alert alert-danger">
      <div ng-show="form.first_name.$error.required">
        First Name is Required
      </div>
      <div ng-show="form.last_name.$error.required">
        Last Name is Required
      </div>
    </div>
    
    </form>
    
  • 1

    您只需要在提交表单之前检查表单是否脏且有效 . 签出以下代码 .

    <form name="frmRegister" data-ng-submit="frmRegister.$valid && frmRegister.$dirty ? register() : return false;" novalidate>
    

    您还可以通过以下更改禁用提交按钮:

    <input type="submit" value="Save" data-ng-disable="frmRegister.$invalid || !frmRegister.$dirty" />
    

    这应该有助于您的初始

  • 0

    这么多复杂的答案 .

    这是我简单的方法 .

    基本上,有两种方法可以解决您的问题 .

    CSS方式:
    当您提交表单无论表单是否有效时,Angular都会向表单元素添加 ng-submitted 类 . 我们可以使用 .ng-submitted 来控制我们的元素 .
    例如

    .error { display: none }
    .ng-submitted .error {
         display: block;
    }
    

    范围方式:
    当您提交表单无论您的表单是否有效时,Angular都会将 [your form name].$submitted 设置为true .

    <div ng-show="customizedFormName.$submitted">error message</div>
    <form name="customizedFormName"></form>
    
  • -3

    http://jsfiddle.net/LRD5x/30/一个简单的解决方案 .

    HTML

    <form ng-submit="sendForm($event)" ng-class={submitted:submitted}>
    

    JS

    $scope.sendForm = function($event) {
      $event.preventDefault()
      $scope.submitted = true
    };
    

    CSS

    .submitted input.ng-invalid:not(:focus) {
        background-color: #FA787E;
    }
    
    input.ng-invalid ~ .alert{
        display:none;
    }
    .submitted input.ng-invalid ~ .alert{
        display:block;
    }
    
  • 3

    我最喜欢realcrowd的解决方案 .

    HTML:

    <form role="form" id="form" name="form" autocomplete="off" novalidate rc-submit="signup()">
    <div class="form-group" ng-class="{'has-error':  rc.form.hasError(form.firstName)}">
        <label for="firstName">Your First Name</label>
        <input type="text" id="firstName" name="firstName" class="form-control input-sm" placeholder="First Name" ng-maxlength="40" required="required" ng-model="owner.name.first"/>
        <div class="help-block" ng-show="rc.form.hasError(form.firstName)">{{rc.form.getErrMsg(form.firstName)}}</div>
    </div>
    </form>
    

    JavaScript的:

    //define custom submit directive
    var rcSubmitDirective = {
    'rcSubmit': ['$parse', function ($parse) {
        return {
            restrict: 'A',
            require: ['rcSubmit', '?form'],
            controller: ['$scope', function ($scope) {
                this.attempted = false;
    
                var formController = null;
    
                this.setAttempted = function() {
                    this.attempted = true;
                };
    
                this.setFormController = function(controller) {
                  formController = controller;
                };
    
                this.hasError = function (fieldModelController) {
                    if (!formController) return false;
    
                    if (fieldModelController) {
                        return fieldModelController.$invalid && this.attempted;
                    } else {
                        return formController && formController.$invalid && this.attempted;
                    }
                };
                this.getErrMsg=function(ctrl){
                    var e=ctrl.$error;
                    var errMsg;
                    if (e.required){
                        errMsg='Please enter a value';
                    }
                    return errMsg;
                }
            }],
            compile: function(cElement, cAttributes, transclude) {
                return {
                    pre: function(scope, formElement, attributes, controllers) {
    
                        var submitController = controllers[0];
                        var formController = (controllers.length > 1) ? controllers[1] : null;
    
                        submitController.setFormController(formController);
    
                        scope.rc = scope.rc || {};
                        scope.rc[attributes.name] = submitController;
                    },
                    post: function(scope, formElement, attributes, controllers) {
    
                        var submitController = controllers[0];
                        var formController = (controllers.length > 1) ? controllers[1] : null;
                        var fn = $parse(attributes.rcSubmit);
    
                        formElement.bind('submit', function (event) {
                            submitController.setAttempted();
                            if (!scope.$$phase) scope.$apply();
    
                            if (!formController.$valid) return false;
    
                            scope.$apply(function() {
                                fn(scope, {$event:event});
                            });
                        });
                    }
              };
            }
        };
    }]
    };
    app.directive(rcSubmitDirective);
    
  • 2
    // This worked for me.
    <form  name="myForm" class="css-form" novalidate ng-submit="Save(myForm.$invalid)">
    <input type="text" name="uName" ng-model="User.Name" required/>
    <span ng-show="User.submitted && myForm.uName.$error.required">Name is required.</span>
    <input ng-click="User.submitted=true" ng-disabled="User.submitted && tForm.$invalid" type="submit" value="Save" />
    </form>
    // in controller
    $scope.Save(invalid)
    {
    if(invalid) return;
    // save form
    }
    
  • 5

    G45,

    我遇到了同样的问题,我创建了一个指令,请在下面查看希望它可能会有所帮助

    指令:

    app.directive('formSubmitValidation', function () {
    
            return {
                require: 'form',
                compile: function (tElem, tAttr) {
    
                    tElem.data('augmented', true);
    
                    return function (scope, elem, attr, form) {
                        elem.on('submit', function ($event) {
                            scope.$broadcast('form:submit', form);
    
                            if (!form.$valid) {
                                $event.preventDefault();
                            }
                            scope.$apply(function () {
                                scope.submitted = true;
                            });
    
    
                        });
                    }
                }
            };
    
    
      })
    

    HTML:

    <form  name="loginForm" class="c-form-login" action="" method="POST" novalidate="novalidate" form-submit-validation="">
    
    <div class="form-group">
                                                    <input type="email" class="form-control c-square c-theme input-lg" placeholder="Email" ng-model="_username" name="_username" required>
                                                    <span class="glyphicon glyphicon-user form-control-feedback c-font-grey"></span>
                                                    <span ng-show="submitted || loginForm._username.$dirty && loginForm._username.$invalid">
                                                        <span ng-show="loginForm._username.$invalid" class="error">Please enter a valid email.</span>
                                                    </span>
                                                </div>
    <button type="submit" class="pull-right btn btn-lg c-theme-btn c-btn-square c-btn-uppercase c-btn-bold">Login</button>
    </form>
    
  • 2

    使用angularjs的验证表单的完整解决方案 .

    HTML如下 .

    <div ng-app="areaApp" ng-controller="addCtrler">
            <form class="form-horizontal" name="fareainfo">
                <div class="form-group">
                      <label for="input-areaname" class="col-sm-2 control-label">Area Name : </label>
                      <div class="col-sm-4">
                          <input type="text" class="form-control" name="name" id="input-areaname" ng-model="Area.Name" placeholder="" required>
                          <span class="text-danger" ng-show="(fareainfo.$submitted || fareainfo.name.$dirty) && fareainfo.name.$error.required"> Field is required</span>
                      </div>
                </div>
                 <div class="col-sm-12">
                      <button type="button" class="btn btn-primary pull-right" ng-click="submitAreaInfo()">Submit</button>
                 </div>
            </form>
        </div>
    

    AngularJS应用程序和控制器如下

    var areaApp = angular.module('areaApp', []); 
    areaApp.controller('addCtrler', function ($scope) {
        $scope.submitAreaInfo = function () {  
           if ($scope.fareainfo.$valid) {
             //after Form is Valid
           } else {
              $scope.fareainfo.$setSubmitted();
           }
        };
    });
    

    重要代码段

    • ng-app="areaApp" ng-controller="addCtrler"
      定义角度应用程序和控制器

    • ng-show="(fareainfo.$submitted || fareainfo.name.$dirty) && fareainfo.name.$error.required"
      以上条件确保每当用户第一次看到表单时,屏幕上没有任何验证错误,并且在用户对表单进行更改后,它确保在屏幕上显示验证消息 . .name. 是input元素的name属性 .

    • $scope.fareainfo.$valid
      在上面的代码中,段会在用户提交表单时检查表单是否有效 .

    • $scope.fareainfo.$setSubmitted();
      在上面的代码中,segment确保每当用户提交表单而不做任何事情时,所有验证消息都会显示在屏幕上 .

  • 12

    试试这段代码:

    <INPUT TYPE="submit" VALUE="Save" onClick="validateTester()">
    

    这个功能将验证您的结果

    function validateTester() {
        var flag = true
        var Tester = document.forms.Tester
        if (Tester.line1.value!="JavaScript") {
            alert("First box must say 'JavaScript'!")
            flag = false
            }
        if (Tester.line2.value!="Kit") {
            alert("Second box must say 'Kit'!")
            flag = false
            }
        if (flag) {
            alert("Form is valid! Submitting form...")
            document.forms.Tester.submit()
            }
        }
    

相关问题