0

I am new to ember, thus I would appreciate your assistance. I want to pass an focus-out event (see bold marked text below) from my handlebars template:

{{input type="text" class="form-control" **focus-out= (action "ccFocusLost" event**) }}

To my action in my controller:

   ccFocusLost : function(**event**) {
        alert(event.relatedTarget.tagName);
    },

However, i get an undefined when I do as above. I need a way to obtain the focus-out event in order to find out which element will receive the focus after my main element loses it.

Thanks in advance!

John
  • 41
  • 10
  • Refer my answer http://stackoverflow.com/a/43736820/5771666 that might give some hint. You cant do this with input helper. – Ember Freak May 03 '17 at 13:06
  • Thanks for the answer. Could you kindly give me an example of how my example above should be modified in order for me to obtain the event in my controller? – John May 03 '17 at 13:16
  • I will try with input helper if no success then we need to go with below options , You can write your own input helper which extends from `Ember.TextField` and inside `focusOut` method, you can call your controller method with `event` object. – Ember Freak May 03 '17 at 13:25
  • I could not achieve it with normal input helper. if you got struggle in creating your own component `my-input` then let me know – Ember Freak May 03 '17 at 13:43

3 Answers3

1

It was tricky, but here is the solution. I have the following code:

template (no need to have an event argument):

{{input type="text" class="form-control" **focus-out= (action "ccFocusLost") }}

Controller:

      ccFocusLost : function() {    
            var targetId= event.relatedTarget.id;       
            alert(targetId);
        },

So it seems that handlebars can access the event, without the need of sending it as an argument. In this case if I press a button with id = button1, the alert will display button1.

John
  • 41
  • 10
0

You can define the focusOut action handler in your controller and check if the event came from your input field with the class "form-control". E.g.

focusOut(event) {
    /* if event did not come from desired input field, return here */
    /* else call the action as desired to process the focusOut event */
}

Alternatively, you could create a component that wraps your input field so you could define the focusOut event at the component level instead of the controller. This would remove the need to check if the event came from the input field.

For more information on handling events in Ember, here is the section of the Guides that provides more detail: Handling Events

zureka
  • 66
  • 3
  • Thanks for the answer. Could you kindly give me a simple example based on my code above? It would be highly appreciated since im very new to Ember – John May 03 '17 at 13:51
  • I create an [example](https://ember-twiddle.com/ba49f45cbd935f65715cc57f26f8f8dd?openFiles=templates.application.hbs%2Ctemplates.components.input-wrapper.hbs) in Ember Twiddle showing the pattern you could follow. Hope it helps! – zureka May 03 '17 at 14:16
  • Great example, and very helpful. Thank you. However, the project im working in is quite complicated, and they do not want new components. Apparently there is a way to do this through:Or, "assign an action to an inline event handler in the template (which creates a closure action and does receive the event object as an argument).". I would be super grateful if you could provide me an example of the mentioned way of achieving this objective. – John May 03 '17 at 15:11
  • I updated the Twiddle to use the inline focusOut handler on the Input Helper. You can view it [here](https://ember-twiddle.com/ba49f45cbd935f65715cc57f26f8f8dd?openFiles=controllers.application.js%2C). My previous version is the pattern I tend to follow since it applies to other areas where handling events is necessary. This should suit your needs though. – zureka May 03 '17 at 16:51
  • Great example, thanks. This seems to be what im looking for. However, when running this code, i get the following message: "Uncaught TypeError: Cannot read property 'setAttribute' of undefined". Maybe worth noting, this project is using ember 1.13. – John May 04 '17 at 08:45
  • Unfortunately I am not familiar with Ember 1.13, I started with Ember 2.x. Looking at the Ember 1.13 Guides shows that the input helper was still able to specify event handlers, but since the Ember API docs aren't versioned yet I can't tell if they previously didn't have support for using `focusOut` instead of the dasherized version: `focus-out`. There might be other areas in your application that follow the pattern you're required to follow. – zureka May 04 '17 at 13:43
0

Two things

  1. If you use focusOut instead of focus-out, the action will automatically include the jQuery event as the argument, no need to specify it in the template.

{{input focusOut=(action "ccFocusLost") }}

  1. In your code, the event is already being passed to your action, it's just that the jQuery event's relatedTarget property is null. This is a jQuery/Javascript event thing, unrelated to Ember. See also here.

There's a lot more information out there on relatedTargets, but it seems it would be better to just use document.activeElement

Community
  • 1
  • 1
  • Thanks for your answer. I tried to replace focus-out with focusOut. However Im getting the following error when running the code: "when running this code, i get the following message: "Uncaught TypeError: Cannot read property 'setAttribute' of undefined". Maybe worth noting, this project is using ember 1.13. Do you have a clue why this occurs? – John May 04 '17 at 09:02