AngularJS 多步表单验证
[英] AngularJS multi-step form validation
本文介绍了AngularJS 多步表单验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我已经关注了
我有一个这样的基本视图:
<div id="顶部"></div><div class="容器"><!-- 视图将在这里注入--><div ui-view></div>
在我的 app.js 中,我有以下内容(不完整,忽略了不重要的事情):
//app.js//创建我们的 Angular 应用程序并注入 ngAnimate 和 ui-router//==============================================================================angular.module('formApp', ['ngAnimate', 'ui.router', 'ui.calendar'])//配置我们的路由//==============================================================================.config(function($stateProvider, $urlRouterProvider, $interpolateProvider) {$interpolateProvider.startSymbol('<%');$interpolateProvider.endSymbol('%>');$stateProvider//路由显示我们的基本表单 (/form).state('表格', {网址:'/表格',templateUrl: 'views/form.html',控制器:'formController'})//嵌套状态//每个部分都有自己的视图//url 将是/form/interests.state('form.license', {网址:'/许可证',templateUrl: 'views/form-license.html'})//url 将被嵌套 (/form/profile).state('form.profile', {网址:'/个人资料',templateUrl: 'views/form-profile.html'})//url 将是/form/payment.state('form.appointment', {url: '/约会',templateUrl: 'views/form-appointment.html'})//url 将是/form/success.state('form.success', {网址:'/成功',templateUrl: 'views/form-success.html'});//捕获所有路由//将用户发送到表单页面$urlRouterProvider.otherwise('/form/license');})//我们的表单控制器//==============================================================================.controller('formController', function($scope, $http, $compile, $location, uiCalendarConfig) {$scope.formData = {};$scope.formData.profile = {};$scope.next = 函数(步骤){如果(步骤== 1){}否则如果(步骤== 2){}};//处理表单的函数$scope.processForm = function(isValid) {};});
我的一般表单.html:
<div class="row"><div class="col-sm-6 col-sm-offset-3"><div id="表单容器"><form id="appointment-form" name="appointmentform" ng-submit="processForm(appointmentform.$valid)"><!-- 我们的嵌套状态视图将在这里注入--><div id="form-views" ui-view></div></表单>
我的表单的第一步是在 form-license.html 中:
<label>Nummerplaat ingeven</label><div class="form-group"><div class="col-xs-8 col-xs-offset-2"><input required type="text" class="form-control" name="license" ng-model="formData.license">
<div class="form-group row"><div class="col-xs-4 col-xs-offset-4"><a ng-click="next(1)" ui-sref="form.profile" class="btn btn-next btn-block">伏尔根德</a>
但现在我想知道如何在他们点击下一步按钮时验证这一点......它不适用于正常的必需属性.
有人可以帮我解决这个问题吗?
更新:
现在我的第一步是:
<a ng-click="next(1, processForm)" ui-sref="form.profile" ng-disabled="!licenseValidated" class="btn btn-next btn-block">伏尔根德</a>
在我的控制器中:
var validateLicense = function (newVal) {var 验证 = 假;//运行您的自定义验证检查如果(新值){验证 = 真;}返回验证;};$scope.$watch('formData.license', function (newVal) {$scope.licenseValidated = validateLicense(newVal);});
好的,那行得通.但是在我的第二步中,我有多个这样的字段:
<div class="form-group"><label class="col-sm-3 control-label" for="name">Name</label><div class="col-sm-9"><input type="text" class="form-control" name="name" ng-model="formData.profile.name">
<div class="form-group"><label class="col-sm-3 control-label" for="street">Street</label><div class="col-sm-9"><input type="text" class="form-control" name="street" ng-model="formData.profile.street">
<div class="form-group"><label class="col-sm-3 control-label" for="zipcode">Zipcode</label><div class="col-sm-9"><input type="text" class="form-control" name="zipcode" ng-model="formData.profile.zipcode">
<div class="form-group row"><div class="col-xs-8 col-xs-offset-2"><a ng-click="next(1)" ui-sref="form.license" class="btn btn-block btn-previous col-xs-3">VORIGE</a><a ng-click="next(2)" ui-sref="form.appointment" class="btn btn-block btn-next col-xs-3">伏尔根德</a>
我需要为每个人都创建一个 $scope.watch 吗?我是否需要将它们添加到我的按钮的 ng-disabled 中?
解决方案
如果任何验证步骤未通过,您可以简单地禁用下一步按钮.
类似于:
//在你的控制器里面.//不要重载范围.//仅通过您的 HTML 或其他 AngularJS 范围分配所需的内容var validateLicense = 函数(newVal){//如果您只是检查要输入的内容return (newVal !== '' && newVal !== undefined);};var validateInfo = 函数(newVal){如果 (newVal.length > 0) {//检查以确保它们都有内容for (var i = 0, l = newVal.length; i < l; i++) {if (newVal[i] === undefined || newVal[i] === '') {返回假;}}//我们没有发现无效数据,让我们继续返回真;}返回假;};var validateDate = 函数(newVal){var 验证 = 假;//运行您的自定义验证检查返回验证;}//初始化禁用的下一步"按钮$scope.licenseValidated = false;$scope.infoValidated = false;//观看表单中的单个项目,如果填写,我们将让他们继续$scope.$watch('formData.license', function (newVal) {$scope.licenseValidated = validateLicense(newVal);});//观察一个表单中的多个项目,如果全部填写,我们将让他们继续//注意这个数组中的顺序是 newVal 的顺序,//因此对 formData.number 的进一步验证将在 newVal[1] 上进行$scope.$watchGroup(['formData.name', 'formData.number', 'formData.address'], 函数 (newVal) {$scope.infoValidated = validateInfo(newVal);});
form-license.html 在下一个按钮上添加 ng-disabled
属性:
<a ng-click="next(1,appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!licenseValidated">伏尔根德</a>
form-info.html 重复以上步骤
<a ng-click="next(1,appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!infoValidated">伏尔根德</a>
等等……
查看此 Fiddle 进行演示
I've followed this tutorial about AngularJS Multi-Step Form Using UI Router. The form works and I can save my data but now I'm having questions about how to validate each step in the form.
I have the following form with input fields:
Step 1
Step 2
- Name
- Street
- Zipcode
- City
- Email
- Telephone
Step 3
- Choose a date & time from a calendar
It looks somewhat like this:
I have a general base view like this:
<body ng-app="formApp">
<div id="top"></div>
<div class="container">
<!-- views will be injected here -->
<div ui-view></div>
</div>
</body>
In my app.js I have the following (not complete, left the non important things out):
// app.js
// create our angular app and inject ngAnimate and ui-router
// =============================================================================
angular.module('formApp', ['ngAnimate', 'ui.router', 'ui.calendar'])
// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider, $interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: 'views/form.html',
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be /form/interests
.state('form.license', {
url: '/license',
templateUrl: 'views/form-license.html'
})
// url will be nested (/form/profile)
.state('form.profile', {
url: '/profile',
templateUrl: 'views/form-profile.html'
})
// url will be /form/payment
.state('form.appointment', {
url: '/appointment',
templateUrl: 'views/form-appointment.html'
})
// url will be /form/success
.state('form.success', {
url: '/success',
templateUrl: 'views/form-success.html'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/license');
})
// our controller for the form
// =============================================================================
.controller('formController', function($scope, $http, $compile, $location, uiCalendarConfig) {
$scope.formData = {};
$scope.formData.profile = {};
$scope.next = function(step){
if(step == 1)
{
}
else if(step == 2)
{
}
};
// function to process the form
$scope.processForm = function(isValid) {
};
});
My general form.html:
<!-- form.html -->
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<div id="form-container">
<form id="appointment-form" name="appointmentform" ng-submit="processForm(appointmentform.$valid)">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
</div>
</div>
The first step in my form is in form-license.html:
<!-- form-license.html -->
<label>Nummerplaat ingeven</label>
<div class="form-group">
<div class="col-xs-8 col-xs-offset-2">
<input required type="text" class="form-control" name="license" ng-model="formData.license">
</div>
</div>
<div class="form-group row">
<div class="col-xs-4 col-xs-offset-4">
<a ng-click="next(1)" ui-sref="form.profile" class="btn btn-next btn-block">
Volgende
</a>
</div>
</div>
But now I'm wondering how I can validate this when they click on next button ... . It's not working with the normal required attribute.
Can somebody help me with this?
UPDATE:
Now I have in my first step the following:
<div class="col-xs-4 col-xs-offset-4">
<a ng-click="next(1, processForm)" ui-sref="form.profile" ng-disabled="!licenseValidated" class="btn btn-next btn-block">
Volgende
</a>
</div>
In my controller:
var validateLicense = function (newVal) {
var validated = false;
// Run your custom validation checks
if(newVal)
{
validated = true;
}
return validated;
};
$scope.$watch('formData.license', function (newVal) {
$scope.licenseValidated = validateLicense(newVal);
});
Ok, that works. But in my second step I have multiple fields like this:
<div class="profile">
<div class="form-group">
<label class="col-sm-3 control-label" for="name">Name</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="name" ng-model="formData.profile.name">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="street">Street</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="street" ng-model="formData.profile.street">
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="zipcode">Zipcode</label>
<div class="col-sm-9">
<input type="text" class="form-control" name="zipcode" ng-model="formData.profile.zipcode">
</div>
</div>
<div class="form-group row">
<div class="col-xs-8 col-xs-offset-2">
<a ng-click="next(1)" ui-sref="form.license" class="btn btn-block btn-previous col-xs-3">
VORIGE
</a>
<a ng-click="next(2)" ui-sref="form.appointment" class="btn btn-block btn-next col-xs-3">
Volgende
</a>
</div>
</div>
</div>
Do I need to create for every one of them a $scope.watch? And do I need to add them to ng-disabled of my button?
解决方案
You could simply disable the next button if any of the validation steps doesn't pass.
Something like:
// Inside your controller.
// Don't overload the scope.
// Only assign what will be needed through your HTML or other AngularJS Scopes
var validateLicense = function (newVal) {
// If you are only checking for content to be entered
return (newVal !== '' && newVal !== undefined);
};
var validateInfo = function (newVal) {
if (newVal.length > 0) {
// Check to make sure that all of them have content
for (var i = 0, l = newVal.length; i < l; i++) {
if (newVal[i] === undefined || newVal[i] === '') {
return false;
}
}
// We didn't find invalid data, let's move on
return true;
}
return false;
};
var validateDate = function (newVal) {
var validated = false;
// Run your custom validation checks
return validated;
}
// Initialize the disabled "Next" buttons
$scope.licenseValidated = false;
$scope.infoValidated = false;
// Watch a single item in a form, if filled in we will let them proceed
$scope.$watch('formData.license', function (newVal) {
$scope.licenseValidated = validateLicense(newVal);
});
// Watch a multiple items in a form, if ALL are filled in we will let them proceed
// Note that the order in this array is the order the newVal will be,
// So further validation for formData.number would be on newVal[1]
$scope.$watchGroup(['formData.name', 'formData.number', 'formData.address'], function (newVal) {
$scope.infoValidated = validateInfo(newVal);
});
form-license.html add the ng-disabled
attribute on your next button:
<a ng-click="next(1, appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!licenseValidated">
Volgende
</a>
form-info.html repeat above steps
<a ng-click="next(1, appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!infoValidated">
Volgende
</a>
And so on...
See this Fiddle for Demo
这篇关于AngularJS 多步表单验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文