How to add class when style is scoped? - templates

This example should paint body in red color, but it doesn't because of scoped attribute.
<template>
<div></div>
</template>
<script>
export default {
name: 'test',
props: {},
mounted(){
document.body.classList.add('highlight');
}
}
</script>
<style lang="scss" scoped>
.highlight {
background-color: red;
}
</style>
Is there some workaround for this case?

You don't need scoped styles because your styles are not scoped to your component.
If you need to have both scoped to component styles and global styles, you should declare two style tags. Example in official docs.
However, you should avoid global styles.

You are applying a scoped class to an element (body) outside the component!
All classes declared in scoped style of a component can be used only for elements inside that component because the class name is automatically changed to something like this: .highlight[2d35fds3sd]!
And all elements inside the component have that unique id :
<template>
<div 2d35fds3sd>
<span 2d35fds3sd> </span>
</div>
</template>
but body element does not have this unique id!
So if you want to apply a class to body, you have to put that class in a global css file.

Related

Is it possible to add class for main route DOMelement?

As in title, is it possible to add something like
classNames
in Component but inside Route or Controller object?
Edited
In application template I add few elements
<header></header>
<div class="content"></div>
<footer></footer>
And as result on page I have:
<div id="ember1122" class="ember-view">
<header></header>
<div class="content"></div>
<footer></footer>
</div>
And I'd like to have
<div id="ember1122" class="ember-view customClassName">
At present, you can't do what you want in a straight forward way.
1. But you can wrap application.hbs content with root div.
Define rootElement in index.html
<div id="my-app" class="customClassName">
{{content-for "body"}}
</div>
inside app.js file, you can change rootElement
import Ember from 'ember';
export default Ember.Application.extend({
rootElement: '#my-app'
});
2.May be you can even try applying styles to application.hbs div using css like
#my-app > .ember-view { // customClassName style goes here }
I don't think this is possible. Altough documentation states that "controller is a specialized component", in fact they are not at all similar.
Component is a subclass of Ember.View. Every time a Component is rendered, there's created a new instance that is hooked to specific part of DOM, has hooks related to rendering, and is aware of DOM elements that it contains.
Controller is an abstract singleton, subclass of Ember.Object. It has functions, properties and actions hooked to rendered template, but doesn't know itself anything about DOM it's attached to.

Base class attribute names for templates with no explicit ember view

So in Ember it's awesome that you don't necessarily need to extend a view for a template and instead one can automagically be created for your template.
My question is, for the base HTML element of a templates automagically created view how can I specify a class name so I can namespace the CSS?
// template /////////////////
<script type="text/x-handlebars" data-template-name="contacts">
...
</script>
// html /////////////////
<div id="ember337" class="ember-view MyCoolClassName"> <---- custom class name in here
...
</div>
I know I can do it by extending a view for this template but to simply add an additional class name that seems overkill. Thoughts?
I think that isn't possible, because the root tag of a view, like this:
<div id="ember337" class="ember-view MyCoolClassName">
is generated from, your properties:
SomeView = Ember.View.create({
elementId: 'ember337',
classNames: ['ember-view', 'MyCoolClassName'],
tagName: 'div'
});
If you don't want to create a view to add a simple class, you can do:
<script type="text/x-handlebars" data-template-name="contacts">
<div class="MyCoolClassName">
Hello world
</div>
</script>
And in your css:
.ember-view .MyCoolClassName {
/*some style */
}

Updating partial style content

I would like to do the following handlebar script:
The color:{{object.labelColor}} seems not working (Cf. other post).
One solution seems to bind the complete style attribute on the "javascript side" but I would like to avoid managing the "fixed" part of the style (text-align:left) on that side.
Is there a solution to make something similar to my sample code (dynamic part on the js side,fixed part on the html view) ?
<div class="label" style="color:{{object.labelColor}};text-align:left">{{object.name}}</div>
You could use 'classNameBindings', and define a set of css rules to the corresponding classes.
Js
Ember.View.create({
classNameBindings: ['isUrgent'] // array of class names
isUrgent: true //conditional to set class name
});
css
.is-urgent{
background-color: #356aa0;
}
Resource
http://emberjs.com/api/classes/Ember.ContainerView.html#property_classNameBindings
If you have to use styles instead of classes, and want to change only a portion of the style strings at the time, one alternative would be using $.css, applying the style changes you want. For example:
<script type="text/x-handlebars">
<h1>App</h1>
{{view App.SomeView}}
</script>
<script type="text/x-handlebars" data-template-name="some-view">
<div style="color:#00F;text-align:left">
Some View<br />
<button {{action changeColor on="click"}}>Change Color</button>
</div>
</script>
<script type="text/javascript">
App = Em.Application.create();
App.SomeView = Em.View.extend({
templateName: 'some-view',
changeColor: function(e) {
console.log('changing color');
this.$('div').css('color', '#F00');
}
});
</script>
In the script above I'm using jQuery's css function to change the color attribute whatever elements my selector returns from within SomeView instance (in this case as I only have one div, I'm using the element as a selector). There are other (and likely better) ways to do this, but I hope this helps.
The problem with this solution as it is, is that you can't keep the state of the style attribute as it's not bound to any property, that's why I think binding classes would be better in the long run.

How to use block instead of inline-block when rendering view

I have implemented a view with multiple {{view Ember.TextField ...}}
The template is displayed BUT all the html elements are displayed inline...
I would like to have all input elements rendered as block.
How to fix that ? (I would like to avoid adding after each view in the template.
You can use the classNames binding inherited from Ember.View to set a css class on the element and define your css styles on it (i.e. display: block;), such as:
{{view Ember.TextField classNames="some-class" ...}}
Alternatively, you can create a subclass of Ember.TextField:
App.MyTextField = Em.TextField.extend({
classNames: ['some-class']
});
And then call this instead in the Handlebars UI:
{{view App.MyTextField ...}}

Ember.js Is there a way to create a custom #ID .class name instead of default ember?

Is there a way to pass in a custom class or id namespace instead of the default ember?
example: turn this
<body class="ember-application">
<div class="ember-view"></div>
</body>
into:
<body class="myapp-application">
<div class="myapp-view"></div>
</body>
You can pass in a custom id, instead of the default "ember-[numview]".
Just set the elementId field of the Ember.View Class
var mainView = Ember.View.create({
tagName: "section",
elementId: "main"
})
will generate:
<section id="main" class="ember-view">
</section>
To remove/modify the default className "ember-view", you need find and edit the classNames field on the PrototypeMixin on the View class...
Em.View.PrototypeMixin.mixins[2].properties.classNames = []
var mainView = Ember.View.create({
tagName: "section",
elementId: "main"
})
will generate:
<section id="main">
</section>
No idea about the side effects...
No.
"ember-application" is hardcoded in Ember.EventDispatcher#setup, and "ember-view" is similarly a static string in the classNames property on Ember.View. Because 'classNames' is a concatenated property (which means subclasses combine their values, instead of replace them), you can add 'myapp-view' to the classNames array, but you can't remove (easily) values from super classes.