Search code examples
odooodoo-12

Add field in wizard view inside inherited module


I have a wizard with a m2m field that displays library.book tree.

In parent module view:

<field name='model'>library.return.wizard</field>
<field name='arch' type='xml'>
    <form string="Return books">
        <sheet>
            <group>
                <field name='book_ids'>
                    <tree>
                        <field name="name"/>
                        <field name="state"/>
                        <!--How to add date_return field here?-->
                        <!--<field name="date_return"/>-->
                    </tree>
                </field>
            </group>
        </sheet>
    </form>
</field>

Another module model inherits library.book and adds a field date_return.

class LibraryBook(models.Model):
    _inherit = 'library.book'

    date_return = fields.Date('Date to return')

I tried to add a date_return field to the wizard view like this, in the child module view:

<field name='model'>library.return.wizard</field>
<field name='arch' type='xml'>
    <field name='book_ids' position="inside">
        <tree>
            <xpath expr="field[@name='state']" position="after">
                <field name="date_return" />
            </xpath>
        </tree>
    </field>
</field>

It doesn't work. What is the right way to address it in the view?

Again, I have a module that inherits m2m field model, and add a field there, but I can't get the field.

UPDATE 22 Jun:

inherit_id definitely helped. Parent record is <record id='library_return_wizard_form' model='ir.ui.view'> so my child view uses <field name="inherit_id" ref="my_library.library_return_wizard_form"/>.

When i only use an element locator, the only column rendered in the tree widget is state.

<record id='library_return_wizard_form_add' model='ir.ui.view'>
    <field name='name'>library.return.wizard.form.view.add</field>
    <field name='model'>library.return.wizard</field>
    <field name="inherit_id" ref="my_library.library_return_wizard_form"/>
    <field name='arch' type='xml'>
        <field name='book_ids' position="inside">
            <tree>
                <field name="state" position="after">
                    <field name="date_return"/>
                </field>
            </tree>
        </field>
    </field>
</record>

If I try to go with xpath, there is a js frontend error.

<record id='library_return_wizard_form_add' model='ir.ui.view'>
    <field name='name'>library.return.wizard.form.view.add</field>
    <field name='model'>library.return.wizard</field>
    <field name="inherit_id" ref="my_library.library_return_wizard_form"/>
    <field name='arch' type='xml'>
        <field name='book_ids' position="inside">
            <tree>
                <xpath expr="//field[@name='book_ids']/tree/field[@name='state']" position="after">
                    <field name="date_return" />
                </xpath>
            </tree>
        </field>
    </field>
</record>

Maybe, just maybe the field is not being found with this xpath, but I doubt it.

Full error:

TypeError: Cannot read property 'type' of undefined
    at Class._renderBodyCell (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:317:55)
    at http://localhost:8069/web/static/src/js/views/list/list_renderer.js:593:25
    at Function._.map._.collect (http://localhost:8069/web/static/lib/underscore/underscore.js:164:24)
    at Class._renderRow [as _super] (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:592:24)
    at Class._renderRow (http://localhost:8069/web/static/src/js/views/list/list_editable_renderer.js:566:32)
    at Class._renderRow (http://localhost:8069/web/static/src/js/core/class.js:123:38)
    at Function._.map._.collect (http://localhost:8069/web/static/lib/underscore/underscore.js:164:24)
    at Class._renderRows (http://localhost:8069/web/static/src/js/views/list/list_renderer.js:614:18)
    at Class._renderRows (http://localhost:8069/web/static/src/js/views/list/list_editable_renderer.js:588:26)
    at Class._renderRows (http://localhost:8069/web/static/src/js/core/class.js:123:38)

In list_renderer.js file xpath node has all it's attributes except expr undefined.

FINAL EDIT:

I should have removed also these few elements which I didn't notice after staring at this one file for too long. Locator or xpath should have been put right into arch.

<field name='book_ids' position="inside">
            <tree>

Solution

  • You should use the inherit_id field to specify the parent view of the current view, it is unset by default.

    You are trying to locate the field named book_ids and add a tree to it which has an XPath expression to locate the state field. The correct way is to locate the state field and use the position attribute to specify how the matched node should be altered.

    <record id="view_library_return_wizard_form" model="ir.ui.view">
        <field name="name">library.return.wizard.form.inherit</field>
        <field name="model">library.return.wizard</field>
        <field name="inherit_id" ref="MODULE_NAME.FORM_VIEW_ID"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='book_ids']/tree/field[@name='state']" position="after">
                <field name="date_return"/>
            </xpath>
        </field>
    </record>
    

    When using an element locator, Odoo will try to find the first element matching. You can use the field locator to simplify the syntax (if there is only one state field or you need to locate the first one).

    <record id="view_library_return_wizard_form" model="ir.ui.view">
        <field name="name">library.return.wizard.form.inherit</field>
        <field name="model">library.return.wizard</field>
        <field name="inherit_id" ref="MODULE_NAME.FORM_VIEW_ID"/>
        <field name="arch" type="xml">
            <field name="state" position="after">
                <field name="date_return"/>
            </field>
        </field>
    </record> 
    

    EDIT::

    Inheritance specs are comprised of an element locator, to match the inherited element in the parent view, and children element that will be used to modify the inherited element.

    You have just to include one of the following expressions in the view arch

    xpath:

    <xpath expr="//field[@name='book_ids']/tree/field[@name='state']" position="after">
        <field name="date_return"/>
    </xpath>
    

    field:

    <field name="state" position="after">
        <field name="date_return"/>
    </field>