luci-base: ui.js: fix UICheckbox widget operation when tooltips are set
authorJo-Philipp Wich <jo@mein.io>
Mon, 29 Mar 2021 09:24:59 +0000 (11:24 +0200)
committerJo-Philipp Wich <jo@mein.io>
Mon, 29 Mar 2021 09:24:59 +0000 (11:24 +0200)
When a tooltip is rendered for a checkbox widget, an additional node is
placed after the checkbox label element, breaking DOM selectors in
bind(), isChecked(), setValue().

Apparently the functionality was never actually tested.

Fixes: #4938
Fixes: e951236e3 ("luci-base: add tooltip handling")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
modules/luci-base/htdocs/luci-static/resources/ui.js

index c8ebef66911c646bd119c71f3deb8a15c155aa0f..3a991be9ac019ec538e561eb46c7aaad6327dec3 100644 (file)
@@ -633,8 +633,9 @@ var UICheckbox = UIElement.extend(/** @lends LuCI.ui.Checkbox.prototype */ {
        bind: function(frameEl) {
                this.node = frameEl;
 
-               this.setUpdateEvents(frameEl.lastElementChild.previousElementSibling, 'click', 'blur');
-               this.setChangeEvents(frameEl.lastElementChild.previousElementSibling, 'change');
+               var input = frameEl.querySelector('input[type="checkbox"]');
+               this.setUpdateEvents(input, 'click', 'blur');
+               this.setChangeEvents(input, 'change');
 
                dom.bindClassInstance(frameEl, this);
 
@@ -650,7 +651,7 @@ var UICheckbox = UIElement.extend(/** @lends LuCI.ui.Checkbox.prototype */ {
         * Returns `true` when the checkbox is currently checked, otherwise `false`.
         */
        isChecked: function() {
-               return this.node.lastElementChild.previousElementSibling.checked;
+               return this.node.querySelector('input[type="checkbox"]').checked;
        },
 
        /** @override */
@@ -662,7 +663,7 @@ var UICheckbox = UIElement.extend(/** @lends LuCI.ui.Checkbox.prototype */ {
 
        /** @override */
        setValue: function(value) {
-               this.node.lastElementChild.previousElementSibling.checked = (value == this.options.value_enabled);
+               this.node.querySelector('input[type="checkbox"]').checked = (value == this.options.value_enabled);
        }
 });