Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Focus an element in Aurelia

I want to set focus to a form element. With jQuery this is so easy, just $('selector').focus.

I have created a simple <input ref="xxx" id="xxx" type="text"> and in my .ts file I add a property and use it here:

attached() {
    this.xxx.focus()
}

Nothing happens. Beginning to feel that some easy things are getting difficult, which I'm sure never was the point.

(the original use case was to set focus to a form element inside a Bootstrap collapse, when the collapse is shown, like this:

// set focus to the first element when the add-cell collapse is shown
$('#collapsedAddTask').on('shown.bs.collapse', function () {
    $('#AddTaskTitle').focus()
})

That works for my basic HTML (not single page app), but not with Aurelia. What's the Aurelia way?

Update Using the answer from Miroslav Popovic below, and in the comments, I got it to work like so (remember, this is a Bootstrap collapse component):

<!-- the heading with an A that toggles visibility -->
<div class="panel-heading">
    <a href="#collapsedAddTask" data-toggle="collapse" id="addTaskHeader" click.delegate="addTaskShown()">Add task</a>
</div>
<!-- the body, which is initially hidden -->
<div class="panel-body">
    <div class="collapse" id="collapsedAddCell">
       <input type="text" focus.bind="addTaskFocused">
       <!-- more controls ... -->
    </div>
</div>
like image 745
specimen Avatar asked Mar 15 '16 08:03

specimen


People also ask

What is a focus element?

The focused element is the element which will receive keyboard and similar events by default.

How do you focus an element in jQuery?

The focus() is an inbuilt method in jQuery which is used to focus on an element. The element get focused by the mouse click or by the tab-navigating button. Here selector is the selected element. Parameter: It accepts an optional parameter “function” which specifies the function to run when the focus event occurs.

Does focus scroll to Element?

An element can be focused by either using the autofocus="true" attribute or calling the element. focus() method. In both cases, the browser will automatically scroll the element into the viewport.


2 Answers

this.xxx.focus() is not working because there is no focus() method on DOM element (EDIT: apparently there is now, although Safari does not support it - https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus, thanks @classicalConditioning). jQuery adds that. Reference created by Aurelia points to a plain DOM element. To make it work, you would need to import jQuery and wrap element:

import $ from 'jquery';

// ...

attached() {
    $(this.xxx).focus();
}

Anyway, you should avoid using jQuery in regular view models. It's OK to use it for custom elements and custom attributes, where you need to interact with DOM or initialize some jQuery plugins.

There is a focus custom attribute in Aurelia. You can read more about it in this Aurelia's blog post.

Basically, it enables you to control the focus from your view model. In your view, you would have this:

<input type="text" focus.bind="hasFocus" value.bind="..."/>

And in view model:

attached() {
    this.hasFocus = true;
}

Of course, you'll probably use that for more complex scenarios. I.e. to focus an input when collapse is expanded, or when a new item is added to array bound with repeat.for.

Also, focus attribute implements two-way binding. In the sample above, it will change the value of hasFocus property accordingly.

like image 129
Miroslav Popovic Avatar answered Oct 05 '22 17:10

Miroslav Popovic


For the situation where the element isn't hidden and you'd like it to have focus once the view has finished loading, you can simply add focus.one-time="true" like so:

<input
  type="text"
  class="form-control"
  focus.one-time="true"
  value.bind="email"
  placeholder="email address">
like image 25
Andrew Avatar answered Oct 05 '22 17:10

Andrew