Ember.js - default template to render into an outlet? - ember.js

So I have a page which looks like the following
[ Nav Bar ]
| |
| Content |
| |
The nav bar I want to be constant across all pages. So the approach I used was to set my page up as follows:
[ Nav Bar ]
{{outlet}}
This is great, I can now render different pages into my outlet for different routes.
But what if I want a default template to be rendered into the outlet for my home page?
I've managed to achieve this by redirecting / to /home, but there must be a better way to do this which allows me to render a default home page at / without re-routing?
Any advice appreciated,
Thanks,
Daniel

To render stuff in the {{outlet}} at the root page /, you have to define a handlerbar script for index:
Your navbar code probably look like this:
<script type="text/x-handlebars">
<div class="navbar ...">
...
</div>
{{outlet}}
</script>
The root page that will be place inside {{outlet}} is the fallowing:
<script type="text/x-handlebars" id="index">
<div class="container">
<h1>Root page!!</h1>
</div>
</script>
In other words, you have to create a handlebar script that will have an id="index".
Should work. It doesn't need any js code to work.

I must admit this property is not well documented and buried in the docs for Ember.View but you could try setting the defaultTemplate property on your ApplicationView. See here for more info on that (search in the page for 'defaultTemplate').
Hope it helps.

The following statement in docs helped me to solve exactly the same problem I was having which is stated in the question:
Ember routing docs
The index template will be rendered into the {{outlet}} in the application template. If the user navigates to /favorites, Ember will replace the index template with the favorites template.
As I am using pod structure in my project, I created an index route having my default template and I placed nav-bar component in my application/template.hbs file.
app/application/template.hbs:
<div id="pageWrapper">
<div id="navbarfixed">{{nav-bar options=options}}</div>
<div id="pageContent">
{{outlet}}
</div>
</div>
app/index/template.hbs
<div id="homeWrapper"> <!--This gets rendered by default in outlet above-->
Some default content of outlet
</div>

Related

EmberJS 1.13 / No more view / Customize application.hbs element / Dont want additional div of ember-view

Ember automatically puts whatever you have in application.hbs inside a <div class='ember-view'>.
For example, if your application.hbs is:
<div class='wrapper'>
...
</div>
The resulting DOM in the browser will be:
<html>
<body>
<div id='ember345' class='ember-view'>
<div class='wrapper'>
...
</div>
</div>
</body>
</html>
That gives me a problem because the 3rd CSS I'm using depends on certain structure. To make it work, it has to be like this:
<html>
<body>
<div class='wrapper'>
...
</div>
</body>
</html>
So I need to tell ember **not** to wrap the content of application.hbs inside that <div id='ember345' class='ember-view'>. How to do that?
Before 1.13 you can make a view (following the naming convention), explained here: How do I customize the view element for the application.hbs template?
But now I'm using 1.13..., and there's no longer the notion of "View"..., and I don't want to use ember-legacy-view add-on (sounds like a step back to me).
Does anybody have a solution?
Thanks,
Raka
Oh... just figured out, you can still create a corresponding view in ember 1.13 (without having to use legacy-view).
I simply did (in ember-cli)
ember g view application
And edit the generated views/application.js to be like this (specify empty string as tagName):
import Ember from 'ember';
export default Ember.View.extend({
tagName: ''
});

Display dynamic content in Ember application template

I am creating an Ember app that manages a list projects and tasks for each project. In the app's navigation, I want to display the name of the selected project. If someone navigates to /projects/1/tasks, I want the page to display project 1's title, along with links to pages specific to that project. Here is what I have started for my application.hbs file of how I expected it to work, however the project title is blank and the links don't work:
<nav id="nav-menu">
<ul>
<li class='menu-project-title'>
{{#link-to 'projects'}}{{project.title}}{{/link-to}}
</li>
<li class='menu-separator'> </li>
<li>{{#link-to 'projects.tasks' project}}Tasks{{/link-to}}</li>
<li>{{#link-to 'projects.people' project}}People{{/link-to}}</li>
</ul>
</nav>
<div class="container" id='main-outlet'>
{{outlet}}
</div>
If I know every route will always have a project returned, what is the best way to pass that data into the application template?
You could use an Ember.computed.readOnly property in your application controller.
App.ApplicationController = Ember.Controller.extend({
needs: ['project'],
activeProject: Ember.computed.readOnly('controllers.project.model')
...
});
But maybe this isn't the best solution. As far as I understand it, the project route/template is always used? So why not move everything to that template.

how to get the generated Ember.Component HTML

I am using Emberjs and Gridsterjs to create some kind of editor. I found out that you need to make a component to include a jQuery plugin in Emberjs. Inside that component i have a number of components that will become the widgets for the Gridster.
this is how i've setup my templates:
<script type="text/x-handlebars">
{{#create-gridster}}
{{create-widget}}
{{/create-gridster}}
</script>
<script type="text/x-handlebars" data-template-name="components/create-gridster">
<button class="btn" {{action 'newWidget'}}>add widget.</button>
<section class="gridster-wrapper">
<div class="gridster">
<ul id="gridster-list">
{{yield}}
</ul>
</div>
</section>
</script>
Now i've created a button that allows the user to add a widget to the Gridster, but i can't seen to find a way to give the requested HTML string for the widget from the component.
I've tried this:
this.get('gridster').add_widget(Ember.Handlebars.compile('{{create-widget}}'));
and this:
this.get('gridster').add_widget(App.CreateWidgetComponent.create().createElement());
but that doesn't seen to work.
QUESTION
My question is how do i create the html string that gridster expects and keep the ember functionality for editting the content.
In myprettycms (myprettycms.codeplex.com) I use gridster to create layout, then to edit the content of the gridster li, I superpose a tiny mce on the slot and I transfert the content of the slot to tinyMCE instance.
When it's finish, I transfert TinyMCEContent in the slot.
See : http://myprettycms.codeplex.com/SourceControl/latest#MyPrettyCMSCommunityManager/Portals/MVC4Portal/Scripts/Views/DynaContentAdmin.js

Remove the rendered application template

I have quite many templates that I render into the application template. The application template, however, has only the {{outlet}} and nothing else.
The home template, must render directly into the application template. But all other templates must be rendered along with the navbar and sidebar.
Currently, I am using partial to render the common data in all the other templates (except 'home')
How can I solve this scenario? All I need is that home should render directly in the body, while all the other templates must render along with the navbar and sidebar.
I might be missing something very obvious here. What should I do to render home in one template and the rest in another?
UPDATE 1
Application Template
{{#unless renderNav}}
{{outlet home}}
{{else}}
{{partial 'navbar'}}
<div class="container">
<div class="row row-offcanvas row-offcanvas-right">
<div class="col-xs-12 col-sm-9">
{{outlet}}
</div>
<div class="col-xs-6 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation">
<div class="list-group">
Link
Link
</div>
</div><!--/span-->
</div><!--/row-->
</div><!--/.container-->
{{/unless}}
UPDATE 2
The above code causes rendering problems. Navigating to the home template causes no issue. But in all other templates, the first page rendered stays on the top while the next pages are rendered below it.
For example, if after 'home', I transition to 'first', 'first' renders two elements A and B.
If I next transition to 'second', which renders C, what I get is A and B and C, instead of C.
UPDATE 3
Solved the error in the previous UPDATE by observing the currentPath property in the application controller. But now in the 'home' route, the 'home' template is not displayed. Instead the navbar is rendered with an empty outlet.
I renamed my outlets and forced HomeRoute to render into outlet 'home'. But still there is no change. All other templates are rendered seamlessly, but 'home' is not rendered at all.
I confirmed that the boolean was false in the HomeRoute, but still the navbar template is being rendered.
You can create a template where navbar and sidebar can be rendered in and all templates except home are nested routes of this new template.
This of course can give you trouble with url, so another way to go is to use a boolean computed property in the application controller based on currentPath that renders or not your partials
e.g.
App.ApplicationController = Ember.Controller.extend({
showPartials: (function() {
this.get('currentPath') != 'home'
}).property('currentPath')
});
Then in your application template do something like
{{#if showPartials}}
{{partial "navbar"}}
{{partial "sidebar"}}
{{/if}}

Ember.js binding a css style in a template

This is solved since Ember 1.8 with the HTMLBars engine.
I would like to bind a css style in a template. What would be the
solution ?
I tried this:
<div class="bar" style="width:{{barWidth}}px"></div>
but DOM element look like this after its been rendered:
<div class="bar" style="width:<script id='metamorph-28-start' type='text/x-placeholder'></script>5.000000000000002<script
id='metamorph-28-end' type='text/x-placeholder'>px">
Obviously here we can see that the tag for metamorph was
added within the style attribute...
I'm wondering what is the best way to achieve such things with
Ember.js
There is something i don't get yet.
I have a template as follow:
<script type="text/x-handlebars" data-template-name="listTemplate">
<ul id="list">
{{#each App.list}}
<li {{bindAttr data-item-id="itemId"}}>
<div>
<span class="label">{{itemName}}</span>
<div class="barContainer">
<div class="bar" {{bindAttr style="barWidth"}}></div>
<div class="barCap"></div>
</div>
</div>
</li>
{{/each}}
</ul>
i'm in a for each loop that loops thru my ArrayProxy content... and the bar width vary depending of the value of each item in the list. Your solution here will not work as the view is the UL and i need a barWidth per model item. and I do not want to polute my Model with css related things like "width: ###px"
Is there any other elegant way to solve what i try to do ? maybe it would be radically different. I'm very new to ember.js and try to discover the best-practices yet:)
Set a string on your view that looks like "width: 100px" and then bind it to your div with the bind-attr helper like so: <div {{bind-attr style="divStyle"}}>Test</div>
http://jsfiddle.net/tomwhatmore/rearT/1/
To simplify all that, I created a tiny handlebars helper for emberjs that allows you to bind any style properties. You can look at https://github.com/yderidde/bindstyle-ember-helper
Add unbound:
<div class="bar" style="width:{{unbound barWidth}}px"></div>
In Ember 2.0:
<div class="bar" style="width:{{barWidth}}px"></div>
will just work.