使用角度ui路由器的多步形式

use*_*195 3 javascript validation angularjs angular-ui-router

我浏览了这篇文章http://scotch.io/tutorials/javascript/angularjs-multi-step-form-using-ui-router#building-our-angular-app-app.js

和plunkr链接是http://plnkr.co/edit/M03tYgtfqNH09U4x5pHC?p=preview

我的问题是如何在此过程中合并表单验证,比如说我们有姓名和电子邮件的第一个表单,我们如何首先验证它并限制移动到下一个表单如果字段为空等等或电子邮件无效.

// create our angular app and inject ngAnimate and ui-router 
// =============================================================================
angular.module('formApp', ['ngAnimate', 'ui.router'])

// configuring our routes 
// =============================================================================
   .config(function($stateProvider, $urlRouterProvider) {

$stateProvider

    // route to show our basic form (/form)
    .state('form', {
        url: '/form',
        templateUrl: 'form.html',
        controller: 'formController'
    })

    // nested states 
    // each of these sections will have their own view
    // url will be nested (/form/profile)
    .state('form.profile', {
        url: '/profile',
        templateUrl: 'form-profile.html'
    })

    // url will be /form/interests
    .state('form.interests', {
        url: '/interests',
        templateUrl: 'form-interests.html'
    })

    // url will be /form/payment
    .state('form.payment', {
        url: '/payment',
        templateUrl: 'form-payment.html'
    });

// catch all route
// send users to the form page 
$urlRouterProvider.otherwise('/form/profile');
})

// our controller for the form
// =============================================================================
.controller('formController', function($scope) {

// we will store all of our form data in this object
$scope.formData = {};

// function to process the form
$scope.processForm = function() {
    alert('awesome!');  
};

});
Run Code Online (Sandbox Code Playgroud)

pca*_*tre 9

所以简单的答案就是每次你要进入下一步时都可以使用angularjs验证机制.这是有效的,因为在示例中,每次我们更改表单上的步骤时,我们都会切换整个表单的内容.因此,如果您将表单命名为"myMultiStepForm",则可以使用myMultiStepForm.$ valid来查看表单是否有效.因此,无论何时用户要更改步骤,您都可以调用函数来检查表单是否有效.例如:

表格名称:

<form name="myMultiStepForm" id="signup-form" ng-submit="processForm()">
    <!-- our nested state views will be injected here -->
    <div id="form-views" ui-view></div>
</form>
Run Code Online (Sandbox Code Playgroud)

按钮移动到下一部分:

<a ng-click="goToNextSection(myMultiStepForm.$valid)" class="btn btn-block btn-info">
    Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
Run Code Online (Sandbox Code Playgroud)

功能转到下一部分:

$scope.goToNextSection=function(isFormValid) {
      // If form is valid go to next section
      if(isFormValid) {
        $state.go(nextState($state.current.name));
      }
};
Run Code Online (Sandbox Code Playgroud)

额外的注意事项,以改善这一点并澄清答案:

首先,在我看来,你正在开始一个带有表单的新项目,所以我会使用最新版本的angularjs(此时它是1.3版本候选版本3),因为它对我们如何使用表单进行了一些改进(对于例如,它改进了验证机制).由于它是候选版本,因此它们现在主要修复错误,API应该是稳定的.你可以在这里阅读更多相关信息.

这是一个带有验证的示例的plunkr链接http://plnkr.co/edit/y7XL9lGxB3wZTIAcxUVS?p=preview

这个例子远非完整我只是在电子邮件字段中添加了验证并更改了"下一步"按钮的行为,以说明检查表单的验证.我使用angularjs 1.3验证(如果你愿意,你可以将它改为1.2,但它会更多逻辑),我将验证添加到电子邮件字段,它只适用于第一步.因此,如果您尝试单击下一步,则在输入有效的电子邮件之前不能.然后你可以点击下一步,它将带你到下一个(这是我停止验证的地方所以其余的例子现在没有意义).

这是我在该字段中添加电子邮件验证的方式:

<div class="form-group">
    <label for="email">Email</label>
    <input type="email" class="form-control" name="email" ng-model="formData.email" required>
    <div ng-messages="myMultiStepForm.email.$error" ng-if="formStepSubmitted || myMultiStepForm.email.$touched">
      <div ng-message="required">The email is required</div>
      <div ng-message="email">Not a valid email</div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

电子邮件是必填的,必须是有效的电子邮件.否则,如果您输入无效值或尝试提交表单,则会收到错误消息.

要将表单验证合并到流程中,您只需添加所需的验证规则,并且每次调用"下一步"按钮都可以验证表单的当前版本,并且只有在有效时才会提前.

为此,我更改了按钮以转到下一步,因此它具有ng-click而不是ui-sref:

<a ng-click="goToNextSection(myMultiStepForm.$valid)" class="btn btn-block btn-info">
    Next Section <span class="glyphicon glyphicon-circle-arrow-right"></span>
</a>
Run Code Online (Sandbox Code Playgroud)

注意我也传递myMultiStepForm.$ valid,myMultiStepForm是我给表单的名字.如果表单有效,则$ valid为true,否则为false.

然后在控制器中我有一个函数,它检查表单是否有效,并且只允许在这种情况下改变状态:

$scope.goToNextSection=function(isFormValid) {
      // set to true to show all error messages (if there are any)
      $scope.formStepSubmitted = true;
      if(isFormValid) {
        // reset this for next form
        $scope.formStepSubmitted = false;

        // mark the step as valid so we can navigate to it via the links
        updateValidityOfCurrentStep(true /*valid */);

        // we only go to the next step if the form is valid
        $state.go(nextState($state.current.name));
      } else {
        // mark the step as valid so we can navigate to it via the links
        updateValidityOfCurrentStep(false /*not valid */);
      }
    };
Run Code Online (Sandbox Code Playgroud)

鉴于用户可以使用顶部的链接进行导航,您还可以拦截开始更改状态的事件(stateChangeStart)并查看上一步是否有效,并且只有在上一步有效时才允许导航.

.value('formSteps', [
  {uiSref: 'form.profile', valid: false},
  {uiSref: 'form.interests', valid: false},
  {uiSref: 'form.payment', valid: false}

  ])
.run([
            '$rootScope',
            '$state',
            'formSteps',
            function($rootScope, $state, formSteps) {

              // Register listener to watch route changes
                $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {

                    var canGoToStep = false;
                    // only go to next if previous is valid
                    var toStateIndex = _.findIndex(formSteps, function(formStep) {
                      return formStep.uiSref === toState.name;

                    });

                    if(toStateIndex === 0) {
                      canGoToStep = true;
                    } else {
                      canGoToStep = formSteps[toStateIndex - 1].valid;
                    }

                    // Stop state changing if the previous state is invalid
                    if(!canGoToStep) {
                        // Abort going to step
                        event.preventDefault();
                    }
                });


            }


        ])
Run Code Online (Sandbox Code Playgroud)

请注意,我创建了一个名为formSteps的值,该值是一个具有所有步骤有效性的数组.只要单击下一步,就会在控制器中更新该有效性.您也可以在更改字段值时执行此操作,以便表单步骤的有效性不依赖于用户单击下一步.