luci-base: ui.js: add generic indicator handling functions
authorJo-Philipp Wich <jo@mein.io>
Tue, 31 Mar 2020 19:29:28 +0000 (21:29 +0200)
committerJo-Philipp Wich <jo@mein.io>
Thu, 7 May 2020 17:40:49 +0000 (19:40 +0200)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit 4250f99d7f061e47d24e18db26bf6dffc98cc72e)

modules/luci-base/htdocs/luci-static/resources/ui.js

index 4a1895667f5ca478de450783a76bf494847d44d1..61ae69f1cbbc58cc9544d4b45fc3b07ee351f958 100644 (file)
@@ -3143,6 +3143,88 @@ var UI = baseclass.extend(/** @lends LuCI.ui.prototype */ {
                return msg;
        },
 
+       /**
+        * Display or update an header area indicator.
+        *
+        * An indicator is a small label displayed in the header area of the screen
+        * providing few amounts of status information such as item counts or state
+        * toggle indicators.
+        *
+        * Multiple indicators may be shown at the same time and indicator labels
+        * may be made clickable to display extended information or to initiate
+        * further actions.
+        *
+        * Indicators can either use a default `active` or a less accented `inactive`
+        * style which is useful for indicators representing state toggles.
+        *
+        * @param {string} id
+        * The ID of the indicator. If an indicator with the given ID already exists,
+        * it is updated with the given label and style.
+        *
+        * @param {string} label
+        * The text to display in the indicator label.
+        *
+        * @param {function} [handler]
+        * A handler function to invoke when the indicator label is clicked/touched
+        * by the user. If omitted, the indicator is not clickable/touchable.
+        *
+        * Note that this parameter only applies to new indicators, when updating
+        * existing labels it is ignored.
+        *
+        * @param {string} [style=active]
+        * The indicator style to use. May be either `active` or `inactive`.
+        *
+        * @returns {boolean}
+        * Returns `true` when the indicator has been updated or `false` when no
+        * changes were made.
+        */
+       showIndicator: function(id, label, handler, style) {
+               if (indicatorDiv == null) {
+                       indicatorDiv = document.body.querySelector('#indicators');
+
+                       if (indicatorDiv == null)
+                               return false;
+               }
+
+               var handlerFn = (typeof(handler) == 'function') ? handler : null,
+                   indicatorElem = indicatorDiv.querySelector('span[data-indicator="%s"]'.format(id)) ||
+                       indicatorDiv.appendChild(E('span', {
+                               'data-indicator': id,
+                               'data-clickable': handlerFn ? true : null,
+                               'click': handlerFn
+                       }, ['']));
+
+               if (label == indicatorElem.firstChild.data && style == indicatorElem.getAttribute('data-style'))
+                       return false;
+
+               indicatorElem.firstChild.data = label;
+               indicatorElem.setAttribute('data-style', (style == 'inactive') ? 'inactive' : 'active');
+               return true;
+       },
+
+       /**
+        * Remove an header area indicator.
+        *
+        * This function removes the given indicator label from the header indicator
+        * area. When the given indicator is not found, this function does nothing.
+        *
+        * @param {string} id
+        * The ID of the indicator to remove.
+        *
+        * @returns {boolean}
+        * Returns `true` when the indicator has been removed or `false` when the
+        * requested indicator was not found.
+        */
+       hideIndicator: function(id) {
+               var indicatorElem = indicatorDiv ? indicatorDiv.querySelector('span[data-indicator="%s"]'.format(id)) : null;
+
+               if (indicatorElem == null)
+                       return false;
+
+               indicatorDiv.removeChild(indicatorElem);
+               return true;
+       },
+
        /**
         * Formats a series of label/value pairs into list-like markup.
         *