在angularjs中显示validation错误消息
我有一个表单,如果点击提交,需要显示validation错误信息。
这是一个工作的笨蛋
<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>
当用户开始进行更改时,validation正常工作。 但它不显示任何错误消息如果点击提交而不input任何内容。
任何想到实现这一目标? 或者以其他方式,当点击“提交”button时,如何使每个input字段变脏
我发现这个小提琴http://jsfiddle.net/thomporter/ANxmv/2/ ,它做了一个漂亮的技巧,导致控制validation。
基本上,它声明了一个范围成员submitted
并设置为true,当你点击提交。 模型错误绑定使用这个额外的expression式来显示错误消息
submitted && form.email.$error.required
UPDATE
正如@哈菲兹的评论 (给他一些upvotes!)所指出的, Angular 1.3+解决scheme很简单:
form.$submitted && form.email.$error.required
由于我使用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>
更新
在我最近的项目中,我使用了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; */ }
很简单!
我也有同样的问题,我解决了这个问题,通过添加一个ng-submit设置variables提交为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>
我喜欢使用$提交的想法,我想我必须将Angular升级到1.3;)
我可以想出两种方法来实现它。
第一个是删除novalidate
来启用浏览器的validation。
其次,当表单无效时,可以禁用save
button
<input ng-disabled="!frmRegister.$valid" type="submit" value="Save" />
希望它有帮助。
我的解决scheme与引导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>
在提交之前,您只需检查表单是否肮脏有效。 签出以下代码。
<form name="frmRegister" data-ng-submit="frmRegister.$valid && frmRegister.$dirty ? register() : return false;" novalidate>
还可以通过以下更改禁用您的提交button:
<input type="submit" value="Save" data-ng-disable="frmRegister.$invalid || !frmRegister.$dirty" />
这应该有助于你的初始
这么多复杂的答案。
这是我简单的方法。
基本上有两种方法来解决你的问题。
CSS方式:
当您提交表单时,无论您的表单是否有效,Angular都会ng-submitted
表单元素添加一个ng-submitted
类。 我们可以使用.ng-submitted
给控制器我们的元素。
例如
.error { display: none } .ng-submitted .error { display: block; }
适用范围:
当您提交表单时,无论您的表单是否有效,Angular都会将[your form name].$submitted
设置[your form name].$submitted
。
<div ng-show="customizedFormName.$submitted">error message</div> <form name="customizedFormName"></form>
http://jsfiddle.net/LRD5x/30/一个简单的解决scheme。;
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; }
我喜欢真正的解决scheme。
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);
// 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 }
G45,
我面临同样的问题,我已经创build了一个指令,请检查下面,希望它可能是有帮助的
指令:
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>
试试这个代码:
<INPUT TYPE="submit" VALUE="Save" onClick="validateTester()">
这个function将validation你的结果
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() } }