Ember-power-select: Trigger focus from an action

Created on 12 May 2016  路  8Comments  路  Source: cibernox/ember-power-select

I am not sure if I am doing this wrong, or if this just isn't supported. I have an action in the component and I would like this action to open and set focus to the ember-power-select element.

When I focus the element, by tabbing or clicking it the onfocus does fire. However, when I use the jquery trigger from the focusSearch() action: power select does not get focus, nor does the onfocus handler fire. I have tried grabbing the classes assocuated with other divs and no luck.

Is there a way to trigger it to open from an action and I am just doing it wrong?

Component.hbs
{{#power-select class='ls-search-box' options=searchList selected=selected onfocus=(action "onfocus") as |item| }} ...
Component.js
actions: { focusSearch(){ //console.log('focus Search'); var input = Ember.$(".ls-search-box ember-power-select-trigger"); if(input) {input.focus();} }, onfocus(){ console.log('onfocus'); },

Most helpful comment

@brancusi Yes, there is cleaner ways.

If the only thing you want to do is to render the component open initially, you can pass initiallyOpened=true. In your example that is enough.

If what you want to do is open or close the component after it has been rendered, there is another way that is not public API yet, but it will be soon, although maybe with a different name. The select accepts an action named registerAPI (I might change that name, but the idea will remain) that will be invoked with an instance of the public API that you can grab and store somewhere to use it as a "remote controller" of the componen later on.

{{#power-select ...blahblah registerAPI=(mut selectRemoteController) as |opt|}}
  {{opt}}
{{/power-select}}

Then in your code

this.get('selectRemoteController').actions.open();
// or even this.get('selectRemoteController').actions.search('foobar'); You can control almost everything of the select.

All 8 comments

@angelosarto This might be a problem with jQuery itself. I remember that jQuery's events don't fire events added with addEventListener. Maybe that is the reason?

I'd need an example to understand what is going on.

I am new to ember and I am current working on a similar issue. Where I am able to get onfocus to fire via clicking or tabbing.

A simliar example with a em-input element would be like

Component.hbs
{{em-input type='text' property='username' placeholder='username' cid ='username-id' }}

Component.js

actions: {
  focusEmInput(){
    Ember.$("#username-id").focus()
  }
}

Where when this action is triggered the {{em-input}} would gain focus, what should I do inorder to mimic this action to a power-select element.

@angelosarto This worked for me, I was using the wrong css selector

Component.hbs

{{#power-select class='ls-search-box' options=searchList selected=selected onfocus=(action "onfocus") as |item| }}

Component.js

actions: {
  focusSearch(){ 
    //console.log('focus Search'); 
    var input = Ember.$(".ls-search-box > .ember-power-select-trigger"); 
    if(input) {
      input.focus();
    } 
  }, 
  onfocus(){ 
    console.log('onfocus'); 
  }, 

Hi,

I would like to do the same thing. The current workaround that we pulled from the test helpers is as follows: Twiddle

triggerOpen(powerSelect) {
    const event = new window.Event('mousedown', { bubbles: true, cancelable: true, view: window });
    powerSelect.dispatchEvent(event);
  },

  didRender() {
    const elm = this.$('.ember-power-select-trigger')[0];
    this.triggerOpen(elm);
  }

Would love a cleaner option if anyone comes across one.

Thank you

@brancusi Yes, there is cleaner ways.

If the only thing you want to do is to render the component open initially, you can pass initiallyOpened=true. In your example that is enough.

If what you want to do is open or close the component after it has been rendered, there is another way that is not public API yet, but it will be soon, although maybe with a different name. The select accepts an action named registerAPI (I might change that name, but the idea will remain) that will be invoked with an instance of the public API that you can grab and store somewhere to use it as a "remote controller" of the componen later on.

{{#power-select ...blahblah registerAPI=(mut selectRemoteController) as |opt|}}
  {{opt}}
{{/power-select}}

Then in your code

this.get('selectRemoteController').actions.open();
// or even this.get('selectRemoteController').actions.search('foobar'); You can control almost everything of the select.

I have a the power select input in a modal and when the modal opens I want the input to be focused. Is the only way to do that still require using css selectors to focus the input?

For now yes, the only way is to target one specific selector from the outside.

For other people looking for this, the correct way to access the publicAPI is:

{{#power-select ...blahblah registerAPI=(action (mut selectRemoteController)) as |opt|}}
  {{opt}}
{{/power-select}}

as described by @cibernox in https://github.com/cibernox/ember-power-select/issues/549#issuecomment-227229404

Was this page helpful?
0 / 5 - 0 ratings