luci-base: form.js: implement readonly property for forms and options

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(cherry picked from commit 9279448148)
This commit is contained in:
Jo-Philipp Wich 2020-04-13 16:53:10 +02:00
parent 4447dea2da
commit 1c935a9963

View file

@ -360,9 +360,20 @@ var CBIMap = CBIAbstractElement.extend(/** @lends LuCI.form.Map.prototype */ {
this.config = config;
this.parsechain = [ config ];
this.readonly = false;
this.data = uci;
},
/**
* Toggle readonly state of the form.
*
* If set to `true`, the Map instance is marked readonly and any form
* option elements added to it will inherit the readonly state.
*
* @name LuCI.form.Map.prototype#readonly
* @type boolean
*/
/**
* Find all DOM nodes within this Map which match the given search
* parameters. This function is essentially a convenience wrapper around
@ -1308,6 +1319,19 @@ var CBIAbstractValue = CBIAbstractElement.extend(/** @lends LuCI.form.AbstractVa
* @default null
*/
/**
* Make option element readonly.
*
* This property defaults to the readonly state of the parent form element.
* When set to `true`, the underlying widget is rendered in disabled state,
* means its contents cannot be changed and the widget cannot be interacted
* with.
*
* @name LuCI.form.AbstractValue.prototype#readonly
* @type boolean
* @default false
*/
/**
* Override the cell width of a table or grid section child option.
*
@ -1960,13 +1984,15 @@ var CBITypedSection = CBIAbstractSection.extend(/** @lends LuCI.form.TypedSectio
createEl.appendChild(E('button', {
'class': 'cbi-button cbi-button-add',
'title': btn_title || _('Add'),
'click': ui.createHandlerFn(this, 'handleAdd')
'click': ui.createHandlerFn(this, 'handleAdd'),
'disabled': this.map.readonly || null
}, [ btn_title || _('Add') ]));
}
else {
var nameEl = E('input', {
'type': 'text',
'class': 'cbi-section-create-name'
'class': 'cbi-section-create-name',
'disabled': this.map.readonly || null
});
dom.append(createEl, [
@ -1981,7 +2007,8 @@ var CBITypedSection = CBIAbstractSection.extend(/** @lends LuCI.form.TypedSectio
return;
return this.handleAdd(ev, nameEl.value);
})
}),
'disabled': this.map.readonly || null
})
]);
@ -2024,7 +2051,8 @@ var CBITypedSection = CBIAbstractSection.extend(/** @lends LuCI.form.TypedSectio
'class': 'cbi-button',
'name': 'cbi.rts.%s.%s'.format(config_name, cfgsections[i]),
'data-section-id': cfgsections[i],
'click': ui.createHandlerFn(this, 'handleRemove', cfgsections[i])
'click': ui.createHandlerFn(this, 'handleRemove', cfgsections[i]),
'disabled': this.map.readonly || null
}, [ _('Delete') ])));
}
@ -2400,7 +2428,8 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
E('div', {
'title': _('Drag to reorder'),
'class': 'btn cbi-button drag-handle center',
'style': 'cursor:move'
'style': 'cursor:move',
'disabled': this.map.readonly || null
}, '☰')
]);
}
@ -2441,7 +2470,8 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
E('button', {
'title': btn_title || _('Delete'),
'class': 'cbi-button cbi-button-remove',
'click': ui.createHandlerFn(this, 'handleRemove', section_id)
'click': ui.createHandlerFn(this, 'handleRemove', section_id),
'disabled': this.map.readonly || null
}, [ btn_title || _('Delete') ])
);
}
@ -2592,6 +2622,7 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
s = m.section(CBINamedSection, section_id, this.sectiontype);
m.parent = parent;
m.readonly = parent.readonly;
s.tabs = this.tabs;
s.tab_names = this.tab_names;
@ -2639,7 +2670,8 @@ var CBITableSection = CBITypedSection.extend(/** @lends LuCI.form.TableSection.p
}, [ _('Dismiss') ]), ' ',
E('button', {
'class': 'cbi-button cbi-button-positive important',
'click': ui.createHandlerFn(this, 'handleModalSave', m)
'click': ui.createHandlerFn(this, 'handleModalSave', m),
'disabled': m.readonly || null
}, [ _('Save') ])
])
], 'cbi-modal');
@ -2926,7 +2958,8 @@ var CBINamedSection = CBIAbstractSection.extend(/** @lends LuCI.form.NamedSectio
E('div', { 'class': 'cbi-section-remove right' },
E('button', {
'class': 'cbi-button',
'click': ui.createHandlerFn(this, 'handleRemove')
'click': ui.createHandlerFn(this, 'handleRemove'),
'disabled': this.map.readonly || null
}, [ _('Delete') ])));
}
@ -2941,7 +2974,8 @@ var CBINamedSection = CBIAbstractSection.extend(/** @lends LuCI.form.NamedSectio
sectionEl.appendChild(
E('button', {
'class': 'cbi-button cbi-button-add',
'click': ui.createHandlerFn(this, 'handleAdd')
'click': ui.createHandlerFn(this, 'handleAdd'),
'disabled': this.map.readonly || null
}, [ _('Add') ]));
}
@ -3135,7 +3169,8 @@ var CBIValue = CBIAbstractValue.extend(/** @lends LuCI.form.Value.prototype */ {
optional: this.optional || this.rmempty,
datatype: this.datatype,
select_placeholder: this.placeholder || placeholder,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
}
else {
@ -3145,7 +3180,8 @@ var CBIValue = CBIAbstractValue.extend(/** @lends LuCI.form.Value.prototype */ {
optional: this.optional || this.rmempty,
datatype: this.datatype,
placeholder: this.placeholder,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
}
@ -3200,7 +3236,8 @@ var CBIDynamicList = CBIValue.extend(/** @lends LuCI.form.DynamicList.prototype
optional: this.optional || this.rmempty,
datatype: this.datatype,
placeholder: this.placeholder,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return widget.render();
@ -3265,7 +3302,8 @@ var CBIListValue = CBIValue.extend(/** @lends LuCI.form.ListValue.prototype */ {
sort: this.keylist,
optional: this.optional,
placeholder: this.placeholder,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return widget.render();
@ -3336,7 +3374,8 @@ var CBIFlagValue = CBIValue.extend(/** @lends LuCI.form.FlagValue.prototype */ {
id: this.cbid(section_id),
value_enabled: this.enabled,
value_disabled: this.disabled,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return widget.render();
@ -3464,7 +3503,8 @@ var CBIMultiValue = CBIDynamicList.extend(/** @lends LuCI.form.MultiValue.protot
select_placeholder: this.placeholder,
display_items: this.display_size || this.size || 3,
dropdown_items: this.dropdown_size || this.size || -1,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return widget.render();
@ -3556,7 +3596,8 @@ var CBITextValue = CBIValue.extend(/** @lends LuCI.form.TextValue.prototype */ {
cols: this.cols,
rows: this.rows,
wrap: this.wrap,
validate: L.bind(this.validate, this, section_id)
validate: L.bind(this.validate, this, section_id),
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return widget.render();
@ -3626,7 +3667,7 @@ var CBIDummyValue = CBIValue.extend(/** @lends LuCI.form.DummyValue.prototype */
hiddenEl = new ui.Hiddenfield(value, { id: this.cbid(section_id) }),
outputEl = E('div');
if (this.href)
if (this.href && !((this.readonly != null) ? this.readonly : this.map.readonly))
outputEl.appendChild(E('a', { 'href': this.href }));
dom.append(outputEl.lastChild || outputEl,
@ -3747,7 +3788,8 @@ var CBIButtonValue = CBIValue.extend(/** @lends LuCI.form.ButtonValue.prototype
ev.currentTarget.parentNode.nextElementSibling.value = value;
return this.map.save();
}, section_id)
}, section_id),
'disabled': ((this.readonly != null) ? this.readonly : this.map.readonly) || null
}, [ btn_title ])
]);
else
@ -3922,7 +3964,8 @@ var CBIFileUpload = CBIValue.extend(/** @lends LuCI.form.FileUpload.prototype */
show_hidden: this.show_hidden,
enable_upload: this.enable_upload,
enable_remove: this.enable_remove,
root_directory: this.root_directory
root_directory: this.root_directory,
disabled: (this.readonly != null) ? this.readonly : this.map.readonly
});
return browserEl.render();