Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to focus a DOM child element from a Meteor event handler

Tags:

dom

meteor

I have an event handler that sets a session variable to change the content within a DOM element -- in this case a table cell.

'dblclick td.itemName': function (evt) {
  Session.set("editItemName",true);
  evt.currentTarget.children[0].focus();
},


                <td class="itemName">
                {{#unless editItemName}}
                    {{name}} 
                {{else}}
                    <input class="editItemName" type="text" value="{{name}}" style="width:100px;">
                {{/unless}}
                </td>

Pretty straight forward...

However evt.currentTarget.children doesnt work. Once the input takes place of the text, I'd like to make it automatically focus... The meteor docs say that this is a DOM object so its weird that the children function doesnt work...

Thanks

Chet

like image 275
Chet Avatar asked Dec 05 '25 03:12

Chet


2 Answers

When you double click, and your function runs, you set the session editItemName to true, and then you're trying to give the input-element focus, but the template has not been re-rendered yet, so the input-element hasn't been created (the template will be re-rendered some time after your function returns). In other words: evt.currentTarget.children[0] is not a reference to the input-element.

Possible solution 1

In HTML 5 there's an attribute called autofocus, which you can use (at least I can in Chrome). Just add it to the input-element:

<input autofocus="autofocus" class="editItemName" type="text" value="{{name}}" style="width:100px;">

Possible solution 2

Otherwise you have to focus it with JavaScript when the template been rendered and your input-element exists in it:

Template.yourTemplate.rendered = function(){

    var input = this.find('.editItemName')

    if(input){
        input.focus()
    }

}
like image 137
Peppe L-G Avatar answered Dec 06 '25 22:12

Peppe L-G


You are trying to set the focus to a DOM element that has not been rendered yet.

The issue has been bothering me for a while. I have tried to use the autofocus='autofocus' HTML attribute: it has no effect in Firefox, and in Chrome, it seems to only work the first time the element is rendered.

So we need a handler that is called just after the template is rendered, in order to set the focus with javascript. Template.templateName.rendered looks like the way to go, but there is an issue:

What didn't work for me:

<template name="itemName">
    <td class="itemName">
    {{#unless editItemName}}
        {{name}} 
    {{else}}
        <input type="text" value="{{name}}">
    {{/unless}}
    </td>
</template>

Template.itemName.rendered = function()
{
    this.$('input').focus() 
}

When doing this, Template.yourTemplate.rendered seems to fire only the first time you click on the item (you get the focus correctly only once).

What worked for me:

<template name="itemName">
    <td class="itemName">
    {{#unless editItemName}}
        {{name}} 
    {{else}}
        {{> itemNameEdit}}
    {{/unless}}
    </td>
</template>

<template name="itemNameEdit">
    <input type="text" value="{{name}}">
</template>

Template.itemNameEdit.rendered = function()
{
    this.$('input').focus() 
}

Any explanation from a Meteor expert?

like image 22
steph643 Avatar answered Dec 06 '25 22:12

steph643



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!