Younes Yaas
Younes Yaas

Reputation: 498

Ionic & Angular JS - How to do a multiple step form?

I've search a lot in Google a solution for do a multiple step form in Ionic (In one view).

I want all data will be retrieved at end in only one submit button for my database (I use Firebase).

I don't found solution and I test a lot, but without success ... Thanks for your time !

EDIT : I've test a Slide solution, but the button next don't work ... This is my code.

HTML :

<ion-slide-box>
<form style="height:100%;" ng-submit="submitEvent(event)">
<button ng-click="slideNext()" style="positon:relative; top:90px;">Next</button>
<ion-slide class="has-header">

  <div style="border-bottom:none !important; background : transparent; text-align:center;">
  <i class="fa fa-edit fa-4x" id="iconstep-ajust"></i>
  <h4 class="text stable" style="font-size: 25px; position: relative; top: 50px;  font-family: lobster;">L'événement</h4>
  </div>
  <img id="separation-step" src="img/line.png"></img>
  <div class="list" style="top:80px;">
  <label class="item item-input item-floating-label" style="border:none;">   
    <input type="text" style="color:#FFF;font-size: 22px;text-align:center;" placeholder="Nom de l'événement" ng-model="event.nameid">
  </label>
  <label class="item item-input item-floating-label" style="border:none;">
    <textarea style="color:#FFF;font-size: 14px;text-align:center;background-color:rgba(255, 255, 255, 0);" placeholder="Description de l'événement" ng-model="event.descriptionid"></textarea>
  </label>
</div>
</ion-slide>

<ion-slide  class="has-header">
  <div style="border-bottom:none !important; background : transparent; text-align:center;">
  <i class="fa fa-clock-o fa-4x" id="iconstep-ajust"></i>
  <h4 class="text stable" style="font-size: 25px; position: relative; top: 50px;  font-family: lobster;">Date/Heure</h4>
  </div>
  <img id="separation-step" src="img/line.png"></img>
  <div class="list" style="top:80px;">
  <label class="item item-input item-floating-label" style="border:none;">
    <input type="date" placeholder="EEE - MMM - yyyy" ng-model-options="{timezone: 'UTC'}" ng-model="event.startdateid" placeholder="Date de début">
  </label>
  <label class="item item-input item-floating-label" style="border:none;">
    <input type="time" placeholder="HH:mm:ss" ng-model-options="{timezone: 'UTC'}" ng-model="event.starthourid" placeholder="Heure de début">
  </label>
</div>
<button class="button button-positive" type="submit" value="Add Event" style="position: relative; top: 90px;">Add</button>

</ion-slide>

Controller JS:

myApp.controller('Step1Ctrl', ['$scope', 'Event', 'Auth', '$rootScope', '$state', '$firebaseArray', '$ionicSlideBoxDelegate', function($scope, Event, Auth, $rootScope, $state, $firebaseArray, $ionicSlideBoxDelegate) {

 $scope.slideNext = function() {

        $ionicSlideBoxDelegate.next();
    }

$scope.submitEvent = function(event) {

    var eventRef = new Firebase("https://myApp.firebaseio.com/Events");
    Event.add(event).then(function (data){ 
      $scope.event = [{userid : null, nameid: null, descriptionid: null, adressid: null, cpid: null, townid: null, startdateid: null, enddateid: null, starthourid: null, endhourid: null}];
     });

  }



  $scope.deleteEvent = function(index) {
    $scope.events.splice(index , 1);
  }

  $scope.auth = Auth;

    // any time auth status updates, add the user data to scope
    $scope.auth.$onAuth(function(authData) {
      $scope.authData = authData;
    });

    $scope.create = function() {
    $state.go('tabstep');
};
$scope.close = function() { 
     $state.go('tabdash'); 
};
}]

)

Service JS :

myApp.factory("Event", ["$firebaseArray", "$firebaseObject", function($firebaseArray, $firebaseObject) {
var eventRef = new Firebase('https://myApp.firebaseio.com/Events/');
var userRef = new Firebase('https://myApp.firebaseio.com/Users/');
var events = $firebaseArray(eventRef);

     var Event = {

         all: events,

         get: function (event){
          var eventInfo = $firebaseObject(eventRef);
          event.startdateid = new Date(event.startdateid);
          event.starthourid = new Date(event.starthourid);
                return $firebaseObject(eventRef.child('Events').child(userid));

              }
            ,
        add: function (event){
          var eventInfo = $firebaseArray(eventRef, userRef);
          event.userid = userRef.getAuth();
          event.startdateid = new Date(event.startdateid).toJSON();
          event.starthourid = new Date(event.starthourid).toJSON();
                return eventInfo.$add(event);
              }
       }
       return Event;

PS : I'm very interested by the Ng-show/hide solution .. An example will be welcome !

Thanks !

Upvotes: 1

Views: 6397

Answers (2)

Sam Storie
Sam Storie

Reputation: 4564

Have you considered using some sort of state variable (like $step) to dynamically show/hide different form elements using ng-show or ng-hide?

I suspect you could still keep a single form element in your HTML, but use this variable to walk a user through multiple sets of form elements. As they work through the steps they'd be updating $scope variables required. The final submit button would then be shown only on the final step, and would be able to use all the variables set during the previous steps.

This isn't really an Ionic specific question, so this is vanilla Angular, but with an HTML template like this:

<body ng-controller="ctrl">
  <h2>Multi-step form demo (on step {{data.step}})</h2>
  <form class="form-horizontal">
  <span ng-show="data.step == 1">
    <input id="value1" type="text" placeholder="Value1" ng-model="data.form.value1"/>
   </span>
  <span ng-show="data.step == 2">
    <input id="value2" type="number" placeholder="Value2" ng-model="data.form.value2"/>
   </span>
    <span ng-show="data.step == 3">
    <input id="value3" type="text" placeholder="Value3" ng-model="data.form.value3"/>
      <a ng-click="submit()">Submit form</a>
   </span>

    <a ng-click="nextStep()">Next</a>

  </form>

  <h2>Form data</h2>
  {{data.form}}

</body>

...and a controller that looks like this:

function ctrl($scope){
  $scope.data = {
    step: 1,
    form: {
      value1: undefined,
      value2: undefined,
      value3: undefined
    }
  }

  $scope.submit = function() {
    alert('form submitted');  
  }

  $scope.nextStep = function() {
    $scope.data.step += 1;
  }
}

...you can start to get what you're looking for. Obviously you'd clean up the code a bit, but this demonstrates the idea.

Here's a working codepen that shows this in action: http://codepen.io/sstorie/pen/vORoay

Upvotes: 1

Jess Patton
Jess Patton

Reputation: 2486

Why not just use a slide box: http://ionicframework.com/docs/api/directive/ionSlideBox/

Once they fill out the info on one page they can simply slide on over the next page to fill in (all in the same ion-view and same controller). Just use the slide delegate to handle the sliding: http://ionicframework.com/docs/api/service/$ionicSlideBoxDelegate/

Then on the last slide just have a submit button, use ng-model on you inputs to store values in a object such as

$scope.inputdata = {answerone: '', answertow: '', answerthree: ''}

and your html will look like:

<input ng-model="inputdata.answerone"></input>

then at the end have a submit button that fires a function on ng-click:

    $scope.submitdata = function(){
        var req = {
            url: yourposturl,
            method: "POST",
            data: $scope.inputdata
        }
        $http(req).success(callbackfuntion).error(callbackfunction).then(callbackfunction)
}

Upvotes: 3

Related Questions