user6506263
user6506263

Reputation:

Dynamically Change CSS Class in Ember

Super, super new to Ember, so apologies if this is straight forward. I want to know the best way to dynamically change properties in a CSS class rendered within a component.

I made a component, like so:

//route_template.hbs
{{map-view point=model}}

And I pass through point, which has two coordinate properties: model.xCoordinate, and model.yCoordinate.

Here's my component template. You can see I am currently using this hacky inline styling to style the point location on the page:

//component_template.hbs
{{#each point as |mapPoint|}}
   <i class="point-icon" style={{html-safe (concat 'left:' mapPoint.xCoordinate 'px; top:' mapPoint.yCoordinate 'px;')}}></i>
{{/each}}

I know: gross. Is there a better way to do this? Should I make a handlebars helper? An action? If someone could just point me in the general direction, I can take it from there. Thanks so much!

Upvotes: 3

Views: 2078

Answers (2)

Mikko Paderes
Mikko Paderes

Reputation: 840

You don't need to use the concat helper in <> type elements. You can do this instead

<i class="point-icon" style="left: {{mapPoint.xCoordinate}}px; top: {{mapPoint.yCoordinate}}px;"></i>

For {{}} blocks though you'll need to use concat

{{my-component style=(concat 'left: ' mapPoint.xCoordinate 'px; top: ' mapPoint.yCoordinate 'px;')}}

Also, if I'm correct, you only need to do html safe if you have markups in your string.

See https://guides.emberjs.com/v3.1.0/templates/writing-helpers/#toc_escaping-html-content

Upvotes: -1

Lux
Lux

Reputation: 18240

have a look at my answer here.

probably ember-css-properties is what you're looking for. Another option is a helper or a computed property.

A helper could offer this API:

<i class="point-icon" style={{build-css
  left=(concat mapPoint.xCoordinate 'px')
  top=(concat mapPoint.yCoordinate 'px')
}}></i>

or even assume px by default:

<i class="point-icon" style={{build-css
  left=concat mapPoint.xCoordinate
  top=concat mapPoint.yCoordinate
}}></i>

if you want to use a computed property you would do this in your template:

<i class="point-icon" style={{myComputedStyle}}></i>

and this in your style

myComputedStyle: computed('mapPoint.{xCoordinate,yCoordinate}', {
  get() {
    return htmlSafe(`
      left: ${xCoordinate}px;
      top: ${yCoordinate}px;
    `);
  }
}),

be careful: with all of theese (except ember-css-properties) you need to understand the implications:

If the user can manipulate mapPoint.xCoordinate or mapPoint.yCoordinate to an unexpected value you may open a security hole!

Upvotes: 2

Related Questions