Ember.js multiple views for same controller OR wizard like routes; how to? - ember.js

Scenario:
You have something like a wizard. The user completes something on the first page, click next and go to second page and so on until he reaches the last page. Here he clicks finish and all his input is stored and persisted using an ember model.
There are two other questions similar to this one:
Ember.js wizard control
Multi-step form (or multiple "pages") in one route using Ember.js
At first I've tried with a route/controller/view for each step, but since the answers are basically a controller's state variables and get lost while transitioning, it is obvious that it cannot work like this!
Then I took the approach described in the above links. One route, one controller, one template with lots of {{#if }} so that I show only the fields of the current step. I think I might improve this by using partials and so each step will have its own template.
The question is: is this the only/the best approach? Does anyone figured out a better way to implement such a flow?

If you make each wizard page a component and then pass the model as a template parameter to each component, you get a pretty nice workflow. The URL is stable (not constantly adding junk onto the end in order to pass state around); it's easy to drop the user into the first step whenever they enter the route (such as manually inputing the URL or perhaps more importantly, finishing the wizard and then hitting the browser's back button); and you can perform validation on each page of the wizard.
Check out my longer answer here

One of the possible approaches would be using Query Parameters so that you can manage a state of each step in a single wizard controller.

Related

When should I use controllers vs routes in EmberJS?

I know this question might seem a little duplicate but the other version of this question is old and some of the content (such as Views) aren't even a part of ember anymore.
I'm about 4 weeks into my internship as a front-end developer working with EmberJS. I still don't understand when it's better to use the route over the controller or vice-versa. It seems to me that every action in the route can also be used in the controller.
The one recent thing I heard was that ember routes should be stateless where as controllers should be stateful.
What is the current state of controllers and routes. When should one be used over the other?
Consider the following example to understand the state of a controller (or route, or anything), in simple terms and in current context -- lets say you have a page (like a form) with three tabs; each tab can be considered as a state - it would call different components based on the state (or the tab you are in). Now if you would happen to go back for some reason, and hit the form link again, you would see that the state would remain the same. (if you were on tab 2 when you hit back, on returning to the form, you would still be on tab 2).
So to maintain these states, controllers are the way to go, since they are singletons. Route would have lost that information, and started fresh. So basically your variables/objects in a controller would define the 'state'.
Route-actions can be as easily used as controller actions- see https://github.com/DockYard/ember-route-action-helper. So if your template for this route is just using model as the object directly, and you don't need to maintain the 'state', you can pretty much do without your controller.
But if your template was using variables which needed manipulation, you would need controller.
Hope this helps!

Ember parent route changes without child route changing

On one Ember route, I have one side a list of records (foos) on the left, and on the other side a form. Usually, I'd route it like so: /foos/bar/1/edit. However, I also have a list of baz records, that can be displayed on the left, next to the form.
Ideally, I'd like to be able to have the user be able to alternate between the two lists on the left, while preserving the form on the right.
My first attempt to do this was to load both lists in the same route, and toggle them with a tab jQuery plugin. However, this poses several problems related to pagination and back button/refreshing.
I've also tried putting the lists in their own routes (i.e. /foos/bars/1/edit and /bazs/bars/1/edit). But I can't figure out how to link to a different list without losing the edit page.
Is there a better way to accomplish this?
I think the best way would be using the separate routes but instead of /foos/bars/1/edit and /bazs/bars/1/edit having the form in the main parent resource then foos and bazs as the sub resources. That way when you transition the routes for which list you want displayed it will changed the template that gets rendered in the outlet but maintaining the form.

Reusable master/detail view best practice ember

I've been grappling with this relatively simple problem in Ember JS in a variety of my apps. I know this may seem like its been answered seven ways to Sunday but I haven't found a solution that I can actually map to my problem.
Okay, so I need a class master/detail view with a route structure like:
Admin Dashboard
Dashboard
Students page (displays a master list of students in a sidebar)
Student page (upon selecting a sidebar item, it is selected and "details appears"
This pattern is reused exactly at three different dashboards in my site. The only difference is the record array of students is different for each one. I'm asking what is the most Ember-esque way to accomplish this?
I have tried multiple solutions but each one has its own problems. Using the {render} helper to render some universal "students" template breaks because I am leveraging the router and <li> tags inside to automatically apply the active class to the selected student, and students.student isn't a route in my router. If I add that route, then it routes away from the dashboard parent route (with the navbar, etc).
I basically want to package this view into a component almost and pass it the array to display, but then how do I add the "active" class? Surely there is an easier way then manually adding and removing the class.
Thoughts?
I apologize if my question isn't super clear! Its a subtle distinction.

Using page sections as route in emberjs

I'm working with a design that has a couple of sections on a single state, and I'd like to be able to link to each section individually.
Is there a way I could render a single template with no outlets at a base level, and then trigger a scroll when transitioning into any of the sub routes?
Additionally, is there a way I could prevent a transition from altering the browsers history, so I could transition around states as the user scrolls without forcing them to hit back several times to escape the page?
The main application template must have an outlet. Else you won't be able to render anything unless you want to do manual rendering with {{render}}. You could put some logic in the template to use with {{render}} but it seems overkill to avoid the convenience of {{outlet}}
You can model your state as a sub state with routes like, post, post/new, post/delete which correspond to routes nested in a post resource.
But, I don't think you can selectively use a route and not affect the url. You can only set the location to none to turn off location changes completely.
I'd just make sure the UI has a contextual back button that takes the user back to the previous state, skipping over states as necessary. So users don't have to rely on the browser's back button too much.

Backbone, selectively render parts in template

I am listing products as table rows, each row contains input fields for specifying the quantity of products.
I made a Fiddle for it here, http://jsfiddle.net/kroofy/4jTa8/19/
As you can see, after the input in the Qty field have been made, the whole row render again. And because of that the focus of the input field will be lost, which is not good if you want to input more than just one digit, or tab between input fields.
What would be the most elegant way to solve this?
I would handle this by setting model.set({qty: _qty}, {silent: true}) and then updating the non-input fields with this.$.
As an alternative to the silent treatment: rather than listening for change events, listen for change:qty and change:sellPrice and have a method that updates just the HTML that needs updating within this.$, rather than re-rendering the DOM object and breaking your focus.
Either way, your comment about "selective updating" on the fiddle is certainly the right way to go.
(this.$ is a backbone hack to jQuery that restricts all selectors to search only within the DOM of the View's element. The element doesn't even need an ID or class; it just needs to exist and the View maintains a handle to it. It's incredibly useful.)
i built a plugin for backbone called Backbone.ModelBinding that may be able to help in this situation. my plugin allows you to update portions of a view with data from a model, when the model changes.
i've forked / updated your fiddle to show it in action: http://jsfiddle.net/derickbailey/FEcyF/6/
i removed the binding to the model change. i've also added id attributes to the inputs of the form to facilitate the plugin (the attribute that the plugin uses is configurable, though). and lastly, i've added a data-bind attribute to the sell price total td.
you can get the plugin here: http://github.com/derickbailey/backbone.modelbinding/
hope that helps
FWIW: my plugin is an automated version of what Elf is suggesting. I've written code exactly like he is describing, numerous times, which is where the plugin came from. I just got tired of writing that code by hand :)