2015-09-24 21 views
8

Ho seguito this tutorial su Modulo Multi-Step AngularJS utilizzando il router UI. Il modulo funziona e posso salvare i miei dati ma ora sto avendo domande su come convalidare ogni passaggio nel modulo.Convalida modulo multi-passo AngularJS

Ho la seguente form con campi di input:

Fase 1

  • targa

Fase 2

  • Nome
  • Via
  • CAP
  • Città
  • Email
  • Telefono

Fase 3

  • Scegliere una data e ora & da un calendario

Sembra un po 'come questo:

enter image description here

ho una vista di base generale come questa:

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

    </div> 
</body> 

Nei miei app.js ho il seguente (non completa, ha lasciato le cose non importanti 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) { 

    }; 

}); 

mio form.html generale:

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

Il primo passo per la mia forma è 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> 

Ma ora mi chiedo come posso convalidare questo quando si fa clic sul pulsante Avanti .... Non funziona con l'attributo normale richiesto.

Qualcuno può aiutarmi con questo?

UPDATE:

Ora ho nel mio primo passo seguente:

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

Nel mio 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, funziona. Ma nel mio secondo passaggio ho più campi come questo:

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

Devo creare per ognuno di loro un $ scope.watch? E devo aggiungerli a ng-disabled del mio pulsante?

risposta

5

Si potrebbe semplicemente disattivare il pulsante accanto se nessuna delle fasi di convalida non passa.

Qualcosa di simile:

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

forma-license.html aggiungere l'attributo ng-disabled sul prossimo tasto:

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

forma-info.html ripetere i passaggi sopra

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

E così via ...

See this Fiddle for Demo

+0

E cosa intendi con i controlli di convalida personalizzati? Ad esempio, richiesto. Basta controllare: if (newVal) {validated = true; }. Come questo? – nielsv

+0

E come posso mostrare errori all'utente? – nielsv

+0

No, 'newVal' è qualunque sia l'input, non è l'oggetto modulo quindi non c'è un controllo' newVal. $ Valid'. Ciò che intendo è, diciamo, che vuoi assicurarti che la licenza abbia almeno 20 caratteri e contenga lettere e numeri o qualcosa del genere. Potresti fare un test regex su questo. '. $ Valid' di Angular controlla solo criteri molto limitati. Come se ci fosse un input o fosse vuoto, ecc. – jnthnjns

3

Hai a disposizione un paio di opzioni a seconda di come vuoi accedervi.

Per iniziare, è necessario utilizzare ng-form per ciascuna delle 3 fasi del modulo. Ciò ti consentirà di convalidare ciascuno individualmente senza doversi preoccupare delle altre sezioni.

Così, a titolo di esempio il primo passo modulo potrebbe trasformarsi in:

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

Ciò consente di accedere alle proprietà di validazione forma proprio per questo passo. A questo punto è possibile aggiornare il controller da utilizzare .$invalid o .$valid sull'oggetto modulo che viene ora passato nella next pulsante di invio, il che significa ora si può fare qualcosa di simile:

$scope.next = function(step, form) { 
    if (form.$invalid) { 
     console.log('Form is invalid!'); 
     return; 
    } 
    // move to next section 
    ... 
}; 
Problemi correlati