Moving between controllers on a page with history

The latest build of Ember.

by Jeremy Gillick

HTML

<script src="http://builds.emberjs.com/handlebars-1.0.0.js"></script>
<script src="http://builds.emberjs.com/ember-latest.js"></script>
<script type="text/x-handlebars" data-template-name="home">
    <h1>Multiple sections with browser history</h1>
    <section>{{outlet sectionOne}}</section>
    <section>{{outlet sectionTwo}}</section>
    <section>{{outlet sectionThree}}</section>
</script>

<script type="text/x-handlebars" data-template-name="sectionOne">
    <div {{bindAttr class="isVisible"}}>
        <h2>Template One</h2>
        <div class="body">
            <p>Foo: {{foo}}</p>
            <p><button {{action didPressContinue}}>Next</button></p>
        </div>
    </div>
</script>
<script type="text/x-handlebars" data-template-name="sectionTwo">
    <div {{bindAttr class="isVisible"}}>
        <h2>Template Two</h2>
        <div class="body">
            <p>Foo: {{foo}}</p>
            <p><button {{action didPressContinue}}>Next</button></p>
        </div>
    </div>
</script>
<script type="text/x-handlebars" data-template-name="sectionThree">
    <div {{bindAttr class="isVisible"}}>
        <h2>Template Three</h2>
        <div class="body">
            <p>Foo: {{foo}}</p>
        </div>
    </div>
</script>

CSS

h1 { font-size: 1.6em; padding-bottom: 10px; }
h2 { font-size: 1.4em; }
section { margin: 7px 0; }
section .body { display: none; }
section .is-visible .body { display: block; }

JavaScript

App = Ember.Application.create({});

// Create route URLs for each section
App.Router.map(function() {
    this.resource('home', function(){
        var routeOrder = [
          'sectionOne',
          'sectionTwo',
          'sectionThree'
        ];
        // Add each route
        for (var i = 0, len = routeOrder.length; i < len; i++) {
          this.route(routeOrder[i]);
        }
        App.Router.sectionOrder = routeOrder;
    });
});

// Index redirects to home (this fiddle doesn't work of index route)
App.IndexRoute = Ember.Route.extend({
    redirect: function(){
        this.transitionTo('home');
    }
});

//
// Handles navigating between sections
//
App.ApplicationRoute = Ember.Route.extend({
    actions: {
        // Open the next section in the order that is not complete
        gotoNextStep: function(){
           console.log('Goto next');
           var sections = App.Router.sectionOrder;
           for (var i = 0; i < sections.length; i++) {
               var section = sections[i],
                   controller = this.controllerFor('home.'+ section);
            
            if (controller && !controller.get('isComplete')) {
              this.transitionTo('home.'+ section);
              return true;
            }
          }
          return false;
        }
    }
});

//
// Build home page with all sections
//
App.HomeRoute = Ember.Route.extend({
    renderTemplate: function (controller, context) {
        this.render();
        
        // Build all the additional sections
        var sections = App.Router.sectionOrder;
        for (var i = 0; i < sections.length; i++) {
          var name = sections[i],
              controllerName = 'home'+ name.classify();
            
          console.log(name);
          this.render(name,
            {
              'outlet': name,
              'into': 'home',
              'controller': controllerName
            });
        }
    },
    
    // Move to the first section immediately
    redirect:...