2015-09-24 3 views
8

Я следил за this tutorial около AngularJS Multi-Step Form с использованием UI-маршрутизатора. Форма работает, и я могу сохранить свои данные, но теперь у меня возникают вопросы о том, как проверить каждый шаг в форме.AngularJS многоступенчатая форма проверки

У меня есть следующие формы с полями ввода:

Шаг 1

  • номерного знака

Шаг 2

  • Имя
  • Улица
  • Zipcode
  • Город
  • Email
  • Телефон

Шаг 3

  • Выберите время, дату & из календаря

Это выглядит примерно так:

enter image description here

У меня есть общий вид базы, как это:

<body ng-app="formApp"> 
    <div id="top"></div> 
    <div class="container"> 
     <!-- views will be injected here --> 
     <div ui-view></div> 

    </div> 
</body> 

В моих app.js я следующее (не полный, оставил Не имеет значения вещи из):

// 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) { 

    }; 

}); 

Мой общий 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> 

Первый шаг в моей форме находится в 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> 

Но теперь мне интересно, как я могу проверить это, когда нажимают на следующую кнопку .... Он не работает с нормальным обязательным атрибутом.

Может ли кто-нибудь помочь мне с этим?

UPDATE:

Теперь у меня есть в моем первом шаге следующее:

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

В мой контроллер:

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

Хорошо, что работает. Но на втором этапе у меня есть несколько полей, как это:

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

Мне нужно создать для каждого из них $ scope.watch ли? И мне нужно добавить их к ng-disabled моей кнопки?

ответ

5

Вы можете просто отключить следующую кнопку если какой-либо из шагов проверки не проходит.

Что-то вроде:

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

форм-license.html добавить атрибут ng-disabled на следующую кнопку:

<a ng-click="next(1, appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!licenseValidated"> 
    Volgende 
</a> 

форм-info.html повторите описанные выше шаги

<a ng-click="next(1, appointmentform)" ui-sref="form.profile" class="btn btn-next btn-block" ng-disabled="!infoValidated"> 
    Volgende 
</a> 

И так далее ...

See this Fiddle for Demo

+0

И что вы имеете в виду с помощью специальных проверок проверки? Например, требуется. Просто проверьте: if (newVal) {validated = true; }. Как это? – nielsv

+0

И как я могу показать ошибки пользователю? – nielsv

+0

Нет, 'newVal' - это какой бы ни был вход, это не объект формы, поэтому нет проверки' newVal. $ Valid'. Я имею в виду, скажем, что вы хотите убедиться, что лицензия не менее 20 символов и содержит буквы и цифры или что-то еще. Вы можете сделать регулярное выражение против этого. Угловая '. $ Valid' проверяет очень ограниченные критерии. Например, если есть вход или он пуст и т. Д. – jnthnjns

3

У вас есть несколько вариантов, доступных вам в зависимости от того, как вы хотите приблизиться к нему.

Чтобы начать, вы должны использовать ng-form для каждого из трех шагов формы. Это позволит вам проверять каждый отдельно, не беспокоясь о других разделах.

Так как например, ваш первый шаг формы может превратиться в:

<ng-form name="LicenseForm"> 
    <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, LicenseForm)" ui-sref="form.profile" class="btn btn-next btn-block"> 
       Volgende 
      </a> 
     </div> 
    </div> 
</ng-form> 

Это дает вам доступ к свойствам валидации формы для всего этого шага. На этом этапе вы можете обновить ваш контроллер использовать .$invalid или .$valid на форме объекта, который в настоящее время передается в next кнопку отправки, то есть теперь вы можете сделать что-то вроде:

$scope.next = function(step, form) { 
    if (form.$invalid) { 
     console.log('Form is invalid!'); 
     return; 
    } 
    // move to next section 
    ... 
}; 
Смежные вопросы