Tarlen
Tarlen

Reputation: 3797

ember autofocus component after insertion into DOM

I want to display an input field, and immediately autofocus it upon clicking a button. Im still new to Ember so i am not sure this is the correct approach, but I tried to wrap as an ember component

template

{{#if showCalendarForm}}
  {{new-calendar focus-out='hideNewCalendar' insert-newline='createCalendar'}}
{{else}}
  <button class="btn btn-sm btn-primary" {{action "showNewCalendar"}}>New</button>
{{/if}}

new-calendar component handlebars:

<div class="input-group">
  {{input
    class       = 'form-control'
    id          = 'newCalendar'
    type        = 'text'
    placeholder = 'New calendar'
    value       = calendarName
    action      = 'createCalendar'
  }}
</div>

new-calendar component js

import Ember from 'ember';

export default Ember.Component.extend({
  didInsertElement: function() {
    this.$().focus();
  }
});

When I click the button, the text field is displayed, but autofocus and hitting enter doesnt work

Upvotes: 4

Views: 1573

Answers (2)

Sam Heuck
Sam Heuck

Reputation: 602

The way the jQuery is written, you are trying to set focus on the <div class="input-group">, try this instead:

didInsertElement: function() {
    this.$('input').focus();
}

Another way to do this would be to extend the Ember.TextField:

export default Ember.TextField.extend({
  becomeFocused: function() {
    this.$().focus();
  }.on('didInsertElement')
});

Then, in your new-calendar template, use this component:

{{focus-input
  class       = 'form-control'
  id          = 'newCalendar'
  type        = 'text'
  placeholder = 'New calendar'
  value       = calendarName
  action      = 'createCalendar'
}}

This way you can reuse the focus-input component wherever you need to.

As for hitting enter to create the calendar, I think you want to listen for the keyPress event, check to see if it's the enter key, and then send the action rather than trying to use insert-newline='createCalendar'.

//in FocusInputComponent

keyPress: function(e) {
  // Return key.
  if (e.keyCode === 13) {
    this.sendAction();
  }
}

Upvotes: 6

benzo
benzo

Reputation: 160

Try wrapping your focus call in an Ember.run and schedule it to be run in the after render queue like this:

didInsertElement: function()
{
    Ember.run.scheduleOnce('afterRender', this, function() {
        this.$().focus();
    });
}

this blog post has helped me a lot in understanding ember's lifecycle hooks: http://madhatted.com/2013/6/8/lifecycle-hooks-in-ember-js-views

Upvotes: 0

Related Questions