javascriptxmlodooodoo-10qweb

How to perform some action when clicking on the field of a tree view in Odoo 10?


I have created my own widget to be called in tree views this way:

<field name="selected" widget="toggle_switch"/>

The field selected is of type boolean. I created the widget class extending the Column class:

var ListView = require('web.ListView');

var ToggleSwitch = ListView.Column.extend({
    template: 'ToggleSwitchSheet',
    events: {
        'click .slider': 'on_click',
    },

    init: function() {
        this._super.apply(this, arguments);
    },

    _format: function(row_data, options) {
        return QWeb.render(this.template, {
            'widget': this,
            'row_data': row_data,
            'prefix': session.prefix,
        });
    },
})

And I have registered it this way:

var core = require('web.core');
core.list_widget_registry.add('field.toggle_switch', ToggleSwitch);

The code of the template:

<t t-name="ToggleSwitchSheet">
    <label class="switch">
        <t t-if="row_data['selected']['value']">
            <input type="checkbox" checked="checked"/>
        </t>
        <t t-if="!row_data['selected']['value']">
            <input type="checkbox"/>
        </t>
        <span class="slider round"></span>
    </label>
</t>

And it is working, but now I want to modify the value of the selected field each time the user clicks on the main element of the template I made for the widget.

The problem is that I am not able to do that. It seems that events dictionary is not available for the Column class, and I cannot use something like this.on('click', this, this.on_click); or this.$el.find(...), as this brings only the field data.

Should I inherit from other classes to use events in my widget (in fact I have tried, but in every case my Qweb template just disappeared from the tree view...)?


Solution

  • I think that you are mixin things here. Or maybe not. Just to be clear Column widgets are intended only to show information. For example to give your personalized html widget to fit properly into the list view. To execute actions there are action buttons that you could use to change the model record value in a python method.

    I know that it's not exactly the same but I'm just setting the bases that you could make your custom widget clickable by using a button in your column with your custom widget associated rendering the result of the checked value inside the button, allowing you to make calls to custom methods in your model to change the record value.

    That been said your widget is almost the same of the ColumnBoolean widget but if you wanna continue with the work done I think that you could do it like this:

    odoo.define('listview_label_click', function (require) {
    "use strict";
    
        var ListView = require('web.ListView');
    
        ListView.List.include({
            init: function (group, opts) {
                this._super.apply(this, arguments);
                this.$current.delegate('td label.switch', 'click', function (e) {
                    e.stopPropagation();
                    // execute your code here, like:
                    var checked = $(e.currentTarget).find('input').prop('checked');
    
                });
            }
        });
    
    });