Using ui-router with a multipart form

42 views
Skip to first unread message

Ben Nelson

unread,
Nov 27, 2014, 9:31:36 PM11/27/14
to ang...@googlegroups.com
So I have a route setup like the following:
'use strict';

module.exports = function($stateProvider, $urlRouterProvider) {
  // For any unmatched url, redirect to /state1
  $urlRouterProvider.otherwise('/');

  // Now set up the states
  $stateProvider
    .state('index', {
      url: '/',
      templateUrl: 'scripts/partials/index.html'
    })
    .state('new-report', {
      url: '/new',
      abstract:true,
      templateUrl: 'scripts/partials/new-report.html',
      deepStateRedirect: true,
      sticky: true,
      controller: 'reportCtrl'
    })
    .state('new-report.first', {
      url: '',
      templateUrl: 'scripts/partials/new-report.first.html',
      controller: 'reportCtrl'
    })
    .state('new-report.second', {
      url: '',
      templateUrl: 'scripts/partials/new-report.second.html'
    })
    .state('new-report.third', {
      url: '',
      templateUrl: 'scripts/partials/new-report.third.html'
    })
    .state('new-report.fourth', {
      url: '',
      templateUrl: 'scripts/partials/new-report.fourth.html'
    })
    .state('new-report.fifth', {
      url: '',
      templateUrl: 'scripts/partials/new-report.fifth.html'
    })
    .state('new-report.sixth', {
      url: '',
      templateUrl: 'scripts/partials/new-report.sixth.html'
    })
    .state('new-report.seventh', {
      url: '',
      templateUrl: 'scripts/partials/new-report.seventh.html'
    })
    .state('new-report.complete', {
      url: '',
      templateUrl: 'scripts/partials/new-report.complete.html'
    })
    .state('my-reports', {
      url: '/reports',
      templateUrl: 'scripts/partials/my-reports.html'
    })
    .state('my-settings', {
      url: '/settings',
      templateUrl: 'scripts/partials/my-settings.html'
    });
};

With a controller of:
'use strict';

module.exports = function($scope) {
  $scope.report = {
    incident_type: ''
  };
  
};


And a set of views like:
<div ui-view='new-report'>

  <div class='side-panel'>
    <h3> Incident Report </h3>
    <div class='divisor text-lowercase white twentyonepx'>
      <hr class='left' /> # <hr class='right' />
    </div>

    <h3> 12&#8209;123456 </h3>

    <ol>
      <hr />
      <li><img ui-sref-active="active-first" class='first' /><a ui-sref='new-report.first'>Type of Fire</a></li>
      <li><img ui-sref-active="active-second" class='second' /><a ui-sref='new-report.second'>Structure</a></li>
      <li><img ui-sref-active="active-third" class='third' /><a ui-sref='new-report.third'>Exposure</a></li>
      <li><img ui-sref-active="active-fourth" class='fourth' /><a ui-sref='new-report.fourth'>Symptoms</a></li>
      <li><img ui-sref-active="active-fifth" class='fifth' /><a ui-sref='new-report.fifth'>Chemicals</a></li>
      <li><img ui-sref-active="active-sixth" class='sixth' /><a ui-sref='new-report.sixth'>Medical Attention</a></li>
      <li><img ui-sref-active="active-seventh" class='seventh' /><a ui-sref='new-report.seventh'>E.M.S</a></li>
    </ol>

    <div class='progress-section'>
      <h3> Progress </h3>
      <br/>
      <div class="progress">
        <div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="60"
              aria-valuemin="0" aria-valuemax="100" style="width: 60%;">

        </div>
      </div>
    </div>

    <div class='submit'>
      <a href='#' class='submit-report'> Submit Report </a>
    </div>
  </div>

  <ng-include src="'scripts/partials/user-info.html'"> </ng-include>

  <div class='report'>
    <ui-view></ui-view>
  </div>
</div>


<div class='report-section first'>
  <div class='header'>
    <hr class='left left-rule'/> Part 1 - Type of Fire <hr class='right' />
  </div>

  <div class='form-group'>
    <div class='left-side'>
    <div class='form-element'>
      <label for='incident-date'>Date of Incident</label>
      <datepicker></datepicker>
    </div>

    <div class='form-element'>
      <label for='incident-type'> Type of Fire </label>
      <select class='form-control' name='incident-type' ng-model='report.incident_type'>
        <option> Chemical </option>
        <option> Option 2 </option>
      </select>
    </div>
  </div>

  <div class='right-side'>
    <div class='form-element'>
      <div class='form-group'>
          <label for='incident-location'>Incident Location</label>
          <input class='form-control' type='text' placeholder='Street' /><br/>
          <input class='form-control' type='text' placeholder='City' /><br/>
          <input class='form-control small' type='text' placeholder='County' />
          <input class='form-control small' type='text' placeholder='Zip' />
        </div>
      </div>
    </div>

    <div class='bottom-btns'>
      <a  ui-sref='new-report.second'>Next</a>
    </div>
  </div>
</div>

My main app load point is set up like the following (I'm using gulp and browserify to help with loading stuff):
'use strict';

//lib dependencies listed out
var $ = require('jquery');
var jQuery = $;
var bootstrap = require('bootstrap');

//controllers
var rootCtrl = require('./controllers/rootCtrl');
var reportCtrl = require('./controllers/reportCtrl');

var ui_router = require('angular-ui-router');
var ui_router_extras = require('ui-router-extras');

var routes = require('./routes');

var namespace = 'main';

var angular = require('angular');

var app = angular.module(namespace, [
    // inject:modules start
    'ui.router',
    'ct.ui.router.extras'
    // inject:modules end
])
.controller('rootCtrl', ['$scope', rootCtrl])
.controller('reportCtrl', ['$scope', reportCtrl])
.config(routes);


module.exports = app;


I want to be able to go between different views of my multipart form using ui-router since it is so SLICK. Only problem is that I can't get my variables on the controller to persist between states. I've tried the ui-router-extras but it hasn't helped, either I'm using it wrong or something else is going wrong. Anyone have experience with this? Basically I want to be able to have a form in 7 parts, each part represented as a state within ui-router with the same controller for each. I want to be able to go back and forth throughout the report process to each state. Each will update a scope variable representing the overall report and at the end I'm going to use $http to post it to my database.

Michael Cranston

unread,
Nov 27, 2014, 9:39:58 PM11/27/14
to ang...@googlegroups.com
Do you have a parent controller of these 7 states that can remember the data along the way? Or is that a shared service between the controllers?

Ben Nelson

unread,
Nov 27, 2014, 9:42:39 PM11/27/14
to ang...@googlegroups.com
The reportCtrl should be shared between all seven, though I don't know if I set it up correctly. I'm kind of new to ui-router so some of this is still magic to me. From what I can tell I just define the controller option in the object I pass to the state as the same and it should be sharing the variables. Though when I update part of the form and then move to another state and try to display that ng-model that was updated I don't see anything, and if I go back to the original state it just defaults to the default state for the ng-model in question.

Hope that makes sense.

Michael Cranston

unread,
Nov 27, 2014, 9:45:33 PM11/27/14
to ang...@googlegroups.com
Why is reportCtrl being used by new-report and new-report.first? Shouldn't it only be used by one?  

Ben Nelson

unread,
Nov 27, 2014, 9:49:14 PM11/27/14
to ang...@googlegroups.com
Should it? I wasn't sure about that. I thought it should be used by the parent as well as the children, but are you saying I should try and set it up differently?

I could set up a parentReportCtrl and then have the children share reportCtrl but I'm not sure if that's the way I should set it up or not.

--
You received this message because you are subscribed to a topic in the Google Groups "AngularJS" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/angular/rOyJoqy9hVg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to angular+u...@googlegroups.com.
To post to this group, send email to ang...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Michael Cranston

unread,
Nov 27, 2014, 9:56:22 PM11/27/14
to ang...@googlegroups.com
You should have one parent controller that maintains the state of your seven child controllers. Then you can have ChildCtrl1, ChildCtrl2, etc, etc. Multiple states shouldn't be using the same controller, i.e. don't do this:

    .state('new-report.first', {
     url: '',
    controller: 'reportCtrl'
    })
    .state('new-report.second', {
    url: '',
   controller: 'reportCtrl'
    })

do this:

  .state('new-report', {
     url
: '',
    controller
: 'parentReportCtrl'

   
})
 
.state('new-report.first', {
     url
: '',

    controller
: 'reportOneCtrl'

   
})
   
.state('new-report.second', {
    url
: '',

   controller
: 'reportTwoCtrl'


If you parentReportCtrl declares an object named $scope.myForm and you start binding stuff in the children to $scope.myForm, that should maintain state throughout.

Ben Nelson

unread,
Nov 27, 2014, 10:39:18 PM11/27/14
to ang...@googlegroups.com
Sweet! Thanks for the help that definitely did the trick! I’ll be sure to holler again if I break anything else! Much appreciated!

Cheers,
-Ben
Reply all
Reply to author
Forward
0 new messages