xmlodooodoo-12

How to create a dynamic label for a form field in Odoo 12?


I have a form view. I added to it the field main_field, but I want to change its label dynamically, depending on the value of other field named conditional_field. This is my main attempt:

<group>
    <group name="xxx">
        <field name="conditional_field" invisible="1"/>
        <label for="main_field" string="AAA" attrs="{'invisible': [('conditional_field', '!=', 'A')]}"/>
        <label for="main_field" string="BBB" attrs="{'invisible': [('conditional_field', '!=', 'B')]}"/>
        <div>
            <field name="main_field" class="oe_inline"/>
        </div>
    </group>
</group>

The problem of this solution is that the labels are always there, just invisible, but actually they are taking space.

If BBB is hidden, main_field appears under the label AAA, because BBB is invisible but taking place at the right of AAA. If AAA is hidden, main_field appears under the label BBB, and BBB is at the right side, because at the left side is the invisible AAA taking place, so it looks even uglier.

The problem is that Odoo is setting display: none; to labels, but is preserving the style of the cell they are in, so my method does not work properly.

Any ideas? I am trying to avoid create auxiliary fields for each label because I have to do this with a lot of labels and that would be a mess. Thank you!


Solution

  • After a lot of attempts, I found a solution. It is not perfect, due to the cell separator: the border disappears, so I had to replicate it with CSS, and it is not as higher as the original one. But it does not look very bad, enough for my situation.

    <group>
        <group name="xxx">
            <field name="conditional_field" invisible="1"/>
                <div class="o_form_label" style="border-right:0.8px solid #ddd; width:101%;">
                    <label for="main_field" string="AAA" attrs="{'invisible': [('conditional_field', '!=', 'A')]}" style="font-weight:bold;"/>
                    <label for="main_field" string="BBB" attrs="{'invisible': [('conditional_field', '!=', 'B')]}" style="font-weight:bold;"/>
                </div>
                <field name="main_field" nolabel="1" style="padding-left:8px;"/>
            </field>
        </group>
    </group>
    

    Obviously, the CSS styles will change depending on which part of the form you are placing the label in. For example, if you want to do this in the classic totals section of invoices, orders, etc. this will be the code:

    <group class="oe_subtotal_footer oe_right">
        <field name="conditional_field" invisible="1"/>
        <div class="oe_right">
            <label for="main_field" string="AAA" attrs="{'invisible': [('conditional_field', '!=', 'A')]}" style="font-weight:bold; margin:0;"/>
            <label for="main_field" string="BBB" attrs="{'invisible': [('conditional_field', '!=', 'B')]}" style="font-weight:bold; margin:0;"/>
        </div>
        <field name="main_field" nolabel="1"/>
    </group>
    

    Anyway, if someone finds a better solution, I will change the accepted answer and give it to them.

    EDIT

    For newer versions, this is an easier solution:

    <div class="o_td_label">
        <label for="main_field" string="AAA" attrs="{'invisible': [('conditional_field', '!=', 'A')]}"/>
        <label for="main_field" string="BBB" attrs="{'invisible': [('conditional_field', '!=', 'B')]}"/>
    </div>
    <field name="main_field" nolabel="1"/>