How to add a class to ember js
<script type="text/x-handlebars">
<div class="wrapper">
<div class="sideMenu">
{{#link-to 'home'}}Home{{/link-to}}
{{#link-to 'posts'}}Posts{{/link-to}}
</div>
<div class="content">
{{outlet}}
</div>
</div>
</script>
I am new to ember js. How to add a class to the "content" class every time the view changes.
source to share
We do something like this:
Ember.Route.reopen({
activate: function() {
var cssClass = this.toCssClass();
// you probably don't need the application class
// to be added to the body
if (cssClass !== 'application') {
Ember.$('body').addClass(cssClass);
}
},
deactivate: function() {
Ember.$('body').removeClass(this.toCssClass());
},
toCssClass: function() {
return this.routeName.replace(/\./g, '-').dasherize();
}
});
It will add a class to the body (in your case, just use content), the same as the current route.
source to share
Just bind the property currentPath
to your application controller to the class of the element in the template:
<div {{bind-attr class=":content currentPath"}}>
{{outlet}}
</div>
If you are not familiar with the syntax {{bind-attr class=
in Ember / Handlebars:
- a class name preceded by a colon (
:content
) is always appended to the element - properties such as
currentPath
cause the current value of that property to be inserted as a class and dynamically updated
To be able to access currentPath
in a template controlled by a controller other than the application controller, first add
needs: ['application']
which makes the application controller available under the name controllers.application
for use in the bind-attr
following way:
<div {{bind-attr class=":content controllers.application.currentPath"}}>
You can use currentRouteName
instead of or in addition to currentPath
if that's better for you.
The added class name will be dashed for example uploads.index
. You can reference this in your CSS avoiding the dot as in
.uploads\.index { }
Or, if you prefer to use dasherized, add a property to give the path to dasherized, for example
dasherizedCurrentPath: function() {
return this.('currentPath').replace(/\./g, '-');
}.property('currentPath')
<div {{bind-attr class=":content dasherizedCurrentPath"}}>
This has been tested in recent versions of ember-cli.
@torazaburo had some great comments regarding @ Asgaroth's answer (accepted), but I liked the idea of โโnot writing the same functionality over and over again. So what I provide below is a hybrid of the two solutions plus my own two cents, and I believe it addresses @torazaburo's concerns regarding the accepted answer.
Let's start at the second point:
I also don't like the idea of โโEmber.Route pollution
Can you contaminate Ember.Route
without contaminants Ember.Route
? (Yes?) Absolutely! :) Instead of overwriting activate
, we can write our own function and tell it to run. .on(activate)
This way our logic runs, but we don't mess around with the built-in / inherited hook activate
.
The accepted answer is very procedural, imperative, jQuery-ish and un-Ember-like.
I have to agree with that too. In the accepted answer, we are ditching the Ember data binding approach and are reverting to jQuery instead. Not only that, we need to have more code in deactivate
order to "clean up the clutter".
So here's my approach:
Ember.Route.reopen({
setContentClass: function(){
this.controllerFor('application').set("path", this.routeName.dasherize());
}.on('activate')
});
We add our own method to the class Ember.Route
without overwriting activate
. This whole method does the property setting path
on the controller application
.
Then, inside the template, application
we can bind to this property:
<div {{bind-attr class=":content path"}}>
{{outlet}}
</div>
Working solution here
source to share