Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a reference of the clicked DOM element to the action handler in Ember

I have a set of buttons whose state I wish to toggle with a class active. If I had a single button, then I would bind the active class to a controller property and toggle that property in the click handler:

<button {{action 'toggle'}} class="{{active}}">model.title</button>

actions: {
  toggle: function() {
    this.set('active', true);
  }
}

But I have multiple buttons, so I am not sure what I can bind. It would be useful if I could pass a reference to the clicked button to the action handler, but I'm not sure how to do this.

{{#each item in model}}
  <button {{action 'toggle' referenceToButton}}>model.title</button>
{{/each}}

actions: {
  toggle: function(buttonReference) {
    // add `active` class to buttonReference
  }
}

What is the best way to accomplish this?

like image 982
Sean Mackesey Avatar asked Apr 07 '15 05:04

Sean Mackesey


3 Answers

Even though the poster got the answer he wanted, I thought I'd post an answer to what I believe was the intention of the original question:

How to get a reference the clicked DOM element from an action? since I came here looking for an answer to that question and didn't find it.

I can't find a way to get the actual element, but you can get the root view element (which wraps the elements defined in the template) via this:

template:

<button {{action 'toggle' this}}>model.title</button>

controller, view, component:

actions: {
  toggle: function(event) {
    // Get element (as in the return value of document.getElementById(id))
    var viewElements = event.element;
    var elementsInTemplate = viewElements.children;
    var button = viewElements.getElementsByTagName('button');
    //also can use getElementsByClassName, use jQuery etc.
  }
}
like image 150
blisstdev Avatar answered Oct 14 '22 09:10

blisstdev


Just another answer...

if you put the action in the onclick (or any other dom event) you will get the "event" javascript object in the last parameter (so you can use event.target to get and manipulate the object)

Template:

<button onclick={{action 'toggle' model.title}}>model.title</button>

Route or controller:

actions: {
  toggle (title, event) {
    // TODO: use title 
    let element = Ember.$(event.target);
    element.toggleClass("active");

    return false;
  }
}

Hope it helps

like image 21
dolcalmi Avatar answered Oct 14 '22 10:10

dolcalmi


Isn't the model-item what you want to pass and not the button?

Then your toggle can just set an attribute on the item which you bind to your button class.

{{#each item in model}}
  <button {{bind-attr class="item.isActive:active"}} {{action 'toggle' item}}>model.title</button>
{{/each}}

actions: {
  toggle: function(item) {
    item.set('isActive', true);
  }
}
like image 33
Mårten Avatar answered Oct 14 '22 09:10

Mårten