采用了棱角分明的UI路由器多步的形式 [英] Multistep form using angular ui router

查看:160
本文介绍了采用了棱角分明的UI路由器多步的形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过这篇文章<一去href=\"http://scotch.io/tutorials/javascript/angularjs-multi-step-form-using-ui-router#building-our-angular-app-app.js\" rel=\"nofollow\">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

我的问题是如何将这一进程中的表单验证,让说的第一种形式,我们有姓名和电子邮件,我们如何才能先验证它并限制移动到下一个形式,如果字段为空或等电子邮件是无效的。

  //创建我们的角度应用程序,并注入ngAnimate和UI路由器
// ================================================ =============================
angular.module('formApp',['ngAnimate','ui.router'])//配置我们的路线
// ================================================ =============================
   的.config(函数($ stateProvider,$ urlRouterProvider){$ stateProvider    //路线,以显示我们的基本形式(/表)
    .STATE('形式',{
        网址:'/表,
        templateUrl:form.html',
        控制器:表单控制器
    })    //嵌套的状态
    //每个部分都会有自己的看法
    // URL将嵌套(/表格/ profile文件)
    .STATE('form.profile',{
        网址:'/个人资料,
        templateUrl:表单profile.html
    })    // URL会/表格/利益
    .STATE('form.interests',{
        网址:'/利益,
        templateUrl:表单interests.html
    })    // URL会/表格/付款
    .STATE('form.payment',{
        网址:'/付款,
        templateUrl:表单payment.html
    });//捕捉所有航线
//用户发送到窗体页
$ urlRouterProvider.otherwise('/表格/ profile文件');
})//我们的表单控制器
// ================================================ =============================
.controller('的FormController',函数($范围){//我们将我们的所有形式的数据存储在这个对象
$ scope.formData = {};//函数来处理的形式
$ scope.processForm =功能(){
    警报('真棒!');
};});


解决方案

所以,简单的答案是你可以使用你每次将要移动到下一个步骤的时间angularjs验证机制。这工作,因为在本例中我们切换整个表格的每一次我们改变表单上步时的内容。正因为如此,如果你的名字,例如一表myMultiStepForm你可以使用myMultiStepForm。$有效,看是否表是否有效。因此,只要用户将改变步骤中,您可以调用一个函数来检查的形式是有效的。例如:

形式与形式的名称:

 &LT;表格名称=myMultiStepFormID =注册表单NG提交=processForm()&GT;
    &LT;! - 我们的嵌套状态的观点将在这里注入 - &GT;
    &LT; D​​IV ID =表单的意见UI-视图&gt;&LT; / DIV&GT;
&LT; /表及GT;

按钮移动到下一个部分:

 &LT;一个NG点击=goToNextSection(myMultiStepForm $有效。)级=BTN BTN-块BTN-INFO&GT;
    接下来章节&lt;跨度类=glyphicon glyphicon圈右箭头&GT;&LT; / SPAN&GT;

功能去下一节:

  $ scope.goToNextSection =功能(isFormValid){
      //如果形式是下一节有效的去
      如果(isFormValid){
        $ state.go(nextState($ state.current.name));
      }
};

额外票据,以改善这一点,并澄清了答案:

首先,在我看来,就像你开始形成一个新的项目,所以我会使用最新版本的angularjs的(此时是1.3候选发布版3),因为它使我们如何能一起工作的几个改进的形式(例如,它提高了验证机制)。因为它是一个发布候选他们大多是现在修复bug和API应该是稳定的。你可以阅读更多关于它这里

下面是与验证<一个一个例子plunkr链接href=\"http://plnkr.co/edit/y7XL9lGxB3wZTIAcxUVS?p=$p$pview\">http://plnkr.co/edit/y7XL9lGxB3wZTIAcxUVS?p=$p$pview

这个例子还远远没有完成我只是说验证电子邮件字段,改变了下一步按钮的行为,以说明检查形式的验证。我用angularjs 1.3验证(你可以,如果你喜欢它更改为1.2,但是这将是一个很大更多的逻辑),我添加了验证的电子邮件字段,它仅适用于第一步。所以,如果你试图点击下一步就可以直到你输入一个有效的电子邮件。然后,您可以点击旁边,它会带你到下一个(这就是我与验证停止这样的例子的其余部分是没有意义的现在)。

这是我如何添加电子邮件验证到外地:

 &LT; D​​IV CLASS =表单组&GT;
    &LT;标签=电子邮件&GT;电子邮件和LT; /标签&gt;
    &LT;输入类型=电子邮件级=表格控NAME =电子邮件NG模型=formData.email要求&GT;
    &LT; D​​IV NG的消息=。myMultiStepForm.email $错误NG-IF =formStepSubmitted || myMultiStepForm.email $感动。&GT;
      &LT; D​​IV NG消息=需要&gt;该电子邮件是必需的&LT; / DIV&GT;
      &LT; D​​IV NG消息=电子邮件&GT;不是一个有效的电子邮件&LT; / DIV&GT;
    &LT; / DIV&GT;
&LT; / DIV&GT;

电子邮件是必需的,它必须是一个有效的电子邮件。否则,你会得到错误信息,如果你把一个无效值或尝试提交表单。

要合并的表单验证进过程中,你只需要添加你想要的验证规则和每次调用'下一步'按钮,验证表单的当前版本,如果它是唯一的有效推进。

对于这个,我改变了按钮进入下一步所以它有一个NG点击,而不是UI的SREF:

 &LT;一个NG点击=goToNextSection(myMultiStepForm $有效。)级=BTN BTN-块BTN-INFO&GT;
    接下来章节&lt;跨度类=glyphicon glyphicon圈右箭头&GT;&LT; / SPAN&GT;
&所述; / A&GT;

请注意,我也通过myMultiStepForm。$有效,myMultiStepForm是我给的形式名称。如果表单是有效的,否则为假 $有效将是真实的。

如果是,则控制器我有检查,如果形式是有效的,只允许在这种情况下的状态变化的函数:

  $ scope.goToNextSection =功能(isFormValid){
      //设置为true以显示所有错误信息(如果有的话)
      $ scope.formStepSubmitted =真;
      如果(isFormValid){
        //重置此为下表
        $ scope.formStepSubmitted = FALSE;        //标记步骤是有效的,所以我们可以通过链接找到它
        updateValidityOfCurrentStep(真/ * *有效/);        //我们只去下一个步骤,如果表单是有效的
        $ state.go(nextState($ state.current.name));
      }其他{
        //标记步骤是有效的,所以我们可以通过链接找到它
        updateValidityOfCurrentStep(假/ *无效* /);
      }
    };

鉴于用户可以使用链接在顶部导航还可以截取开始改变状态(stateChangeStart)的事件,并查看是否previous步骤是有效的,并只允许当$导航p $ pvious步骤是有效的。

  .value的('formSteps',[
  {uiSref:form.profile,有效期:假},
  {uiSref:form.interests,有效期:假},
  {uiSref:form.payment,有效期:假}  ])
。跑([
            '$ rootScope',
            '$州',
            formSteps',
            功能($ rootScope,$状态,formSteps){              //注册监听器观看路由变化
                $ rootScope。在$('$ stateChangeStart',函数(事件,toState,toParams,fromState,fromParams){                    VAR canGoToStep = FALSE;
                    //只去下一个,如果previous有效
                    VAR toStateIndex = _.findIndex(formSteps,功能(formStep){
                      返回formStep.uiSref === toState.name;                    });                    如果(toStateIndex === 0){
                      canGoToStep = TRUE;
                    }其他{
                      canGoToStep = formSteps [toStateIndex - 1] .valid;
                    }                    //停止状态改变,如果previous状态无效
                    如果(!canGoToStep){
                        //中止继续到步骤
                        。事件preventDefault();
                    }
                });
            }
        ])

通知我创建一个值称为formSteps即具有的所有步骤的有效性的阵列。这种有效性的,只要你点击下一步控制器的更新。你也可以做到这一点的字段值的变化,从而表单步骤的有效性不依赖于用户点击下一步。

I went through this article http://scotch.io/tutorials/javascript/angularjs-multi-step-form-using-ui-router#building-our-angular-app-app.js

and the plunkr link is http://plnkr.co/edit/M03tYgtfqNH09U4x5pHC?p=preview

My question is how to incorporate form validation within this process, let say for the first form where we have name and the email, how we can we validate it first and restrict moving to the next form if fields are empty etc. or email is invalid.

// 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!');  
};

});

解决方案

So the simple answer is you can just use angularjs validation mechanisms every time you are about to move to the next step. This works because in the example we switch the content of the entire form every time we change the step on the form. Because of this, if you name a form for example "myMultiStepForm" you can use myMultiStepForm.$valid to see if the form is valid or not. So whenever the user is going to change the step you can call a function to check if the form is valid. For example:

Form with form name:

<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>

Button to move to next section:

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

Function to go to next section:

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

Extra notes to improve this and clarify the answer:

First of all it seems to me like you are starting a new project with forms so I would use the latest version of angularjs (at this time it is 1.3 release candidate 3) because it makes several improvements on how we can work with forms (for example it improves validation mechanisms). Since it is a release candidate they are mostly fixing bugs now and the API should be stable. You can read more about it here.

Here is the plunkr link with an example with validation http://plnkr.co/edit/y7XL9lGxB3wZTIAcxUVS?p=preview

This example is far from complete I just added validation to the email field and changed the behaviour of the 'next' button in order to illustrate checking the validation of the form. I use angularjs 1.3 validation (you can change it to 1.2 if you like but it will be a lot more logic), I added that validation to the email field and it only works for the first step. So if you try to click next you can't until you enter a valid email. Then you can click next and it will take you to the next one (that's where I stopped with the validation so the rest of the example is meaningless for now).

This is how I added email validation to the field:

<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>

The email is required and it has to be a valid email. Otherwise you get error message if you put an invalid value or try to submit the form.

To incorporate form validation into the process you just add the validation rules you want and for every call to the 'next step' button you validate the current version of the form and only advance if it is valid.

For this I changed the button to go to next step so it has an ng-click instead of 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>

Notice I also pass myMultiStepForm.$valid, myMultiStepForm is the name I gave to the form. $valid will be true if the form is valid and false otherwise.

Then in the controller I have a function that checks if the form is valid and only allows a change in state in that case:

$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 */);
      }
    };

Given that the user can use the links on the top to navigate you can also intercept the event of starting to change the state (stateChangeStart) and see if the previous step is valid and only allow the navigation if the previous step is valid.

.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();
                    }
                });


            }


        ])

Notice I created a value called formSteps that is an array that has the validity of all the steps. That validity is updated in the controller whenever you click next step. You could also do it on change of the field value so that the validity of the form step does not depend on the user clicking next.

这篇关于采用了棱角分明的UI路由器多步的形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆