虽说AngularJS的实时表单验证很是有用,很是高效方便,可是当用户尚未完成输入时便弹出一个错误提示,这种体验是很是糟糕的。app
正常的表单验证逻辑应该是在用户提交表单后或完成当前字段中的输入后,再提示验证信息,这样才是用户友好的。下面就来看看如何实现wordpress
在用户试图提交表单时,你能够在做用域中捕获一个submitted值,而后对表单内容进行验证并显示错误信息。ui
下面经过一个简单的例子来讲明,只在用户提交表单时才显示错误信息。在ng-show 指令中添加对submitted(判断表单是否提交)的检查,仅有当submitted的值为true(即表示表单已提交)同时该表单元素是处于$invalid状态的时候,错误信息就会显示出来spa
HTML代码rest
<form name="registerForm" class="registerForm" novalidate ng-submit="register(user)"> <div class="title">欢迎注册,和咱们一块儿甜蜜生活</div> <div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div> <input type="text" name="username" class="form-control" placeholder="请输入手机号码" ng-model="user.username" maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/"/> </div> <div class="form-error" ng-show="registerForm.username.$invalid && submitted "> <span ng-show="registerForm.username.$error.required">手机号不能为空</span> <span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span> </div> </div> <input type="submit" value="注册" class="btn btn-register btn-tianmi"/> {{result}} </form>
Controller代码code
$scope.submitted = false $scope.register = function (user) { //表单正常提交 if($scope.registerForm.$valid){ //正常提交表单 } else{ $scope.submitted = true; } };
经过上面的方法,即可以实现用户在有非法输入的状况下提交表单,将显示错误信息orm
要想保留用户在输入某个字段失焦后提示错误信息,须要实现一个ngFocus的指令,并在表单中添加该指令blog
ngFocus指令代码element
.directive('ngFocus', function () { var FOCUS_CLASS = "ng-focused"; return{ restrict:'A', require:'ngModel', link: function (scope, element, attrs,ctrl) { ctrl.$focused = false; element.bind('focus', function (evt) { element.addClass(FOCUS_CLASS); scope.$apply(function () { ctrl.$focused = true; }); }).bind('blur', function () { element.removeClass(FOCUS_CLASS); scope.$apply(function(){ ctrl.$focused = false; }) }) } } })
接下来将ngFocus指令添加到input的元素上就可使用该指令,依然用上面的表单例子作用域
<form name="registerForm" class="registerForm" novalidate ng-submit="register(user)"> <div class="title">欢迎注册,和咱们一块儿甜蜜生活</div> <div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div> <input type="text" name="username" class="form-control" placeholder="请输入手机号码" ng-model="user.username" maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/" ng-focus/> </div> <div class="form-error" ng-show="registerForm.username.$invalid && !registerForm.username.$focused "> <span ng-show="registerForm.username.$error.required">手机号不能为空</span> <span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span> </div> </div> <input type="submit" value="注册" class="btn btn-register btn-tianmi"/> {{result}} </form>
ngFocus指令给表单输入字段的blur和focus添加了相应的行为,添加了一个名为ng-focused的类,并将$focused的值设置为true。这样就能够经过判断表单是否具备焦点来显示错误信息
<div class="form-error" ng-show="registerForm.username.$invalid && !registerForm.username.$focused "> <span ng-show="registerForm.username.$error.required">手机号不能为空</span> <span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span> </div>
固然了,在正常的状况下,咱们通常是使用失焦后验证+表单提交后验证两种方式相结合的形式来进行表单验证。下面就经过一个完整的用户注册例子来显示若是实现这种验证方式。
HTMl代码
<form name="registerForm" class="registerForm" novalidate ng-submit="register(user)"> <div class="title">欢迎注册,和咱们一块儿甜蜜生活</div> <div class="form-group " ng-class="registerForm.username.$invalid ? '' : 'has-success'"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-phone"></span></div> <input type="text" name="username" class="form-control" placeholder="请输入手机号码" ng-model="user.username" maxlength="11" required ng-pattern="/1[3|5|7|8|][0-9]{9}/" ng-focus/> </div> <div class="form-error" ng-show="(registerForm.username.$invalid && registerForm.username.$dirty && !registerForm.username.$focused) || (registerForm.username.$invalid && submitted )"> <span ng-show="registerForm.username.$error.required">手机号不能为空</span> <span ng-show="registerForm.username.$error.pattern">请输入正确的手机号码</span> </div> </div> <div class="form-group row sms-code-row"> <div class="col-xs-6 input-sms-code"> <input type="text" value="" name="sms_code" class="form-control" ng-model="user.sms_code" placeholder="请输入6位验证码" required ng-maxlength="6" maxlength="6"/> </div> <div class="col-xs-6 btn-sms-code"> <button type="button" class="btn btn-default btn-register btn-tianmi" ng-click="getVerifyCode(user.username)" ng-disabled="sms_code_status || registerForm.username.$invalid">{{sms_code_content}} </button> </div> <div class="clearfix"></div> <div class="form-error" ng-show="(registerForm.sms_code.$invalid && registerForm.sms_code.$dirty) ||(registerForm.sms_code.$invalid && submitted) "> <span ng-show="registerForm.sms_code.$error.required">请输入验证码</span> </div> </div> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-key"></span></div> <input type="password" name="password" ng-model="user.password" class="form-control" placeholder="请输入登陆密码" required ng-focus minlength="6" ng-pattern="/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$/"/> </div> <div class="form-error" ng-show="(registerForm.password.$invalid && registerForm.password.$dirty && !registerForm.password.$focused) || (registerForm.password.$invalid && submitted)"> <span ng-show="registerForm.password.$error.minlength">密码不能少于6位</span> <span ng-show="registerForm.password.$error.pattern">密码必须由数字和字母组成</span> <span ng-show="registerForm.password.$error.required">密码不能为空</span> </div> </div> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-key"></span></div> <input type="password" name="repeat_password" class="form-control" ng-model="user.repeat_password" ng-focus placeholder="请再次输入密码" required pw-check match="user.password"/> <!--<span class="iconfont icon-yonghu"></span>--> </div> <div class="form-error" ng-show="(registerForm.repeat_password.$invalid && registerForm.repeat_password.$dirty && registerForm.repeat_password.$focused) || (registerForm.repeat_password.$invalid && submitted)"> <span ng-show="registerForm.repeat_password.$error.required">密码不能为空</span> <span ng-show="registerForm.$error.matchError">两次密码不同</span> </div> </div> <div class="form-group"> <div class="input-group"> <div class="input-group-addon"><span class=" iconfont icon-register icon-yonghu"></span></div> <input type="text" name="nick_name" class="form-control" ng-model="user.nick_name" placeholder="请输入昵称" minlength="2" maxlength="20" ng-focus ng-pattern="/^[a-zA-Z0-9\u0391-\uFFE5]{2,20}$/ " required/> </div> <div class="form-error" ng-show="(registerForm.nick_name.$invalid && registerForm.nick_name.$dirty && registerForm.nick_name.$focused) || (registerForm.nick_name.$invalid && submitted)"> <span ng-show="registerForm.nick_name.$error.required">昵称不能为空</span> <span ng-show="registerForm.nick_name.$error.pattern">昵称为2-20个字符,可由中文、字母和数字组成</span> </div> </div> <div class="checkbox"> <label> <input type="checkbox" name="protocol" ng-model="protocol" required> 赞成 <a class="protocol" href="http://123.57.246.184/wordpress/?p=1941" target="_blank">添米用户注册协议</a> 和 <a class="protocol" href="http://123.57.246.184/wordpress/?p=1939" target="_blank">添米投资服务协议</a> </label> <div class="form-error" ng-show="!protocol && submitted"> <span>请先赞成协议</span> </div> </div> <input type="submit" value="注册" class="btn btn-register btn-tianmi"/> {{result}} </form>
controller代码
$scope.submitted = false $scope.register = function (user) { //表单正常提交 if($scope.registerForm.$valid){ //正常提交表单 } else{ $scope.submitted = true; } };