luci-base: form.js: add AbstractValue.onchange property

Introduce a new, widget agnostic onchange property which allows setting
custom handler functions to react on element value changes.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
Jo-Philipp Wich 2020-08-03 15:34:07 +02:00
parent 572090101d
commit 2d774c4973

View file

@ -1374,6 +1374,21 @@ var CBIAbstractValue = CBIAbstractElement.extend(/** @lends LuCI.form.AbstractVa
* @default null * @default null
*/ */
/**
* Register a custom value change handler.
*
* If this property is set to a function value, the function is invoked
* whenever the value of the underlying UI input element is changing.
*
* The invoked handler function will receive the DOM click element as
* first and the underlying configuration section ID as well as the input
* value as second and third argument respectively.
*
* @name LuCI.form.AbstractValue.prototype#onchange
* @type function
* @default null
*/
/** /**
* Add a dependency contraint to the option. * Add a dependency contraint to the option.
* *
@ -3120,6 +3135,20 @@ var CBIValue = CBIAbstractValue.extend(/** @lends LuCI.form.Value.prototype */ {
.then(this.renderFrame.bind(this, section_id, in_table, option_index)); .then(this.renderFrame.bind(this, section_id, in_table, option_index));
}, },
/** @private */
handleValueChange: function(section_id, state, ev) {
if (typeof(this.onchange) != 'function')
return;
var value = this.formvalue(section_id);
if (isEqual(value, state.previousValue))
return;
state.previousValue = value;
this.onchange.call(this, ev, section_id, value);
},
/** @private */ /** @private */
renderFrame: function(section_id, in_table, option_index, nodes) { renderFrame: function(section_id, in_table, option_index, nodes) {
var config_name = this.uciconfig || this.section.uciconfig || this.map.config, var config_name = this.uciconfig || this.section.uciconfig || this.map.config,
@ -3189,6 +3218,9 @@ var CBIValue = CBIAbstractValue.extend(/** @lends LuCI.form.Value.prototype */ {
if (depend_list && depend_list.length) if (depend_list && depend_list.length)
optionEl.classList.add('hidden'); optionEl.classList.add('hidden');
optionEl.addEventListener('widget-change',
L.bind(this.handleValueChange, this, section_id, {}));
optionEl.addEventListener('widget-change', optionEl.addEventListener('widget-change',
L.bind(this.map.checkDepends, this.map)); L.bind(this.map.checkDepends, this.map));