Search code examples
javascriptxmlfocusodooodoo-10

How to focus a field which is in a TransientModel form in Odoo?


I've just realized that default_focus="1" does not work for fields in Transient Model views (at least the ones opened with target="new"). And autofocus="autofocus", which I thought it should be used only with buttons or pages, works for those Transient Model fields, but only the first time you open the view. It is not working again unless you reload the browser.

In my case, I did a widget for a Char field (inside the Transient Model), and I need this field to be focused each time the pop-up is opened. As I am not able to do it by XML, I am trying to do it in JavaScript.

This is the XML template of my widget, which is inheriting from FieldChar:

<t t-name="FieldRed" t-extend="FieldChar">
    <t t-jquery="input" t-operation="attributes">
        <attribute name="id">barcode_input</attribute>
        <attribute name="class">o_form_input bg-red</attribute>
    </t>
</t>

Now, the JS code of my widget. I am trying to focus it in start method because is the first method executed after the renderisation:

start: function() {
    console.log('START');
    this._super.apply(this, arguments);
    this.$el.parent().find('input').focus();
},

But this is not working. I've also tried with:

this.setupFocus(this.$el.parent().find('input'));

But nothing happened. However, if I include this line, for example, the field is automatically filled in, as expected:

this.$el.parent().find('input').val('START');

So my question is:

How can I focus the input field of the widget each time the form is opened?


Solution

  • Finally, I've just found a simple workaround for this. I just wait for 50 miliseconds before calling the focus, with setTimeout. I guess the focus is automatically moved by the Odoo core to somewhere when start is called, if I wait for the end of that action and then move the focus wherever I want, it works. Not a solution I like, though, but at the moment it's the only one I have:

    start: function() {
        this._super.apply(this, arguments);
        self = this;
        setTimeout(function(){
            self.$el.parent().find('input').focus();
        }, 50);
    },