var x = E('div', {}, s);
return x.textContent || x.innerText || '';
+ },
+
+ titleFn: function(attr /*, ... */) {
+ var s = null;
+
+ if (typeof(this[attr]) == 'function')
+ s = this[attr].apply(this, this.varargs(arguments, 1));
+ else if (typeof(this[attr]) == 'string')
+ s = (arguments.length > 1) ? ''.format.apply(this[attr], this.varargs(arguments, 1)) : this[attr];
+
+ if (s != null)
+ s = this.stripTags(String(s)).trim();
+
+ if (s == null || s == '')
+ return null;
+
+ return s;
}
});
return Promise.all(tasks);
},
- save: function() {
+ save: function(cb, silent) {
this.checkDepends();
return this.parse()
+ .then(cb)
.then(uci.save.bind(uci))
.then(this.load.bind(this))
- .then(this.renderContents.bind(this))
.catch(function(e) {
- alert('Cannot save due to invalid values')
+ if (!silent)
+ alert('Cannot save due to invalid values');
+
return Promise.reject();
- });
+ }).finally(this.renderContents.bind(this));
},
reset: function() {
if (this.description != null && this.description != '')
mapEl.appendChild(E('div', { 'class': 'cbi-map-descr' }, this.description));
- L.dom.append(mapEl, nodes);
+ if (this.tabbed)
+ L.dom.append(mapEl, E('div', { 'class': 'cbi-map-tabbed' }, nodes));
+ else
+ L.dom.append(mapEl, nodes);
if (!initialRender) {
mapEl.classList.remove('flash');
this.checkDepends();
+ var tabGroups = mapEl.querySelectorAll('.cbi-map-tabbed, .cbi-section-node-tabbed');
+
+ for (var i = 0; i < tabGroups.length; i++)
+ ui.tabs.initTabGroup(tabGroups[i].childNodes);
+
return mapEl;
}, this));
},
- lookupOption: function(name, section_id) {
+ lookupOption: function(name, section_id, config_name) {
var id, elem, sid, inst;
if (name.indexOf('.') > -1)
id = 'cbid.%s'.format(name);
else
- id = 'cbid.%s.%s.%s'.format(this.config, section_id, name);
+ id = 'cbid.%s.%s.%s'.format(config_name || this.config, section_id, name);
elem = this.findElement('data-field', id);
sid = elem ? id.split(/\./)[2] : null;
else if (k.indexOf('.') !== -1)
dep['cbid.%s'.format(k)] = list[i][k];
else
- dep['cbid.%s.%s.%s'.format(this.config, this.ucisection || section_id, k)] = list[i][k];
+ dep['cbid.%s.%s.%s'.format(
+ this.uciconfig || this.section.uciconfig || this.map.config,
+ this.ucisection || section_id,
+ k
+ )] = list[i][k];
}
}
istat = false;
}
else {
- var res = this.map.lookupOption(dep, section_id),
+ var conf = this.uciconfig || this.section.uciconfig || this.map.config,
+ res = this.map.lookupOption(dep, section_id, conf),
val = res ? res[0].formvalue(res[1]) : null;
istat = (istat && isEqual(val, this.deps[i][dep]));
if (section_id == null)
L.error('TypeError', 'Section ID required');
- return 'cbid.%s.%s.%s'.format(this.map.config, section_id, this.option);
+ return 'cbid.%s.%s.%s'.format(
+ this.uciconfig || this.section.uciconfig || this.map.config,
+ section_id, this.option);
},
load: function(section_id) {
L.error('TypeError', 'Section ID required');
return uci.get(
- this.uciconfig || this.map.config,
+ this.uciconfig || this.section.uciconfig || this.map.config,
this.ucisection || section_id,
this.ucioption || this.option);
},
write: function(section_id, formvalue) {
return uci.set(
- this.uciconfig || this.map.config,
+ this.uciconfig || this.section.uciconfig || this.map.config,
this.ucisection || section_id,
this.ucioption || this.option,
formvalue);
remove: function(section_id) {
return uci.unset(
- this.uciconfig || this.map.config,
+ this.uciconfig || this.section.uciconfig || this.map.config,
this.ucisection || section_id,
this.ucioption || this.option);
}
var config_name = this.uciconfig || this.map.config;
uci.add(config_name, this.sectiontype, name);
- this.map.save();
+ return this.map.save(null, true);
},
handleRemove: function(section_id, ev) {
var config_name = this.uciconfig || this.map.config;
uci.remove(config_name, section_id);
- this.map.save();
+ return this.map.save(null, true);
},
renderSectionAdd: function(extra_class) {
return E([]);
var createEl = E('div', { 'class': 'cbi-section-create' }),
- config_name = this.uciconfig || this.map.config;
+ config_name = this.uciconfig || this.map.config,
+ btn_title = this.titleFn('addbtntitle');
if (extra_class != null)
createEl.classList.add(extra_class);
if (this.anonymous) {
- createEl.appendChild(E('input', {
- 'type': 'submit',
+ createEl.appendChild(E('button', {
'class': 'cbi-button cbi-button-add',
- 'value': _('Add'),
- 'title': _('Add'),
- 'click': L.bind(this.handleAdd, this)
- }));
+ 'title': btn_title || _('Add'),
+ 'click': L.ui.createHandlerFn(this, 'handleAdd')
+ }, btn_title || _('Add')));
}
else {
var nameEl = E('input', {
E('input', {
'class': 'cbi-button cbi-button-add',
'type': 'submit',
- 'value': _('Add'),
- 'title': _('Add'),
- 'click': L.bind(function(ev) {
+ 'value': btn_title || _('Add'),
+ 'title': btn_title || _('Add'),
+ 'click': L.ui.createHandlerFn(this, function(ev) {
if (nameEl.classList.contains('cbi-input-invalid'))
return;
- this.handleAdd(ev, nameEl.value);
- }, this)
+ return this.handleAdd(ev, nameEl.value);
+ })
})
]);
return createEl;
},
+ renderSectionPlaceholder: function() {
+ return E([
+ E('em', _('This section contains no values yet')),
+ E('br'), E('br')
+ ]);
+ },
+
renderContents: function(cfgsections, nodes) {
var section_id = null,
config_name = this.uciconfig || this.map.config,
sectionEl = E('div', {
'id': 'cbi-%s-%s'.format(config_name, this.sectiontype),
- 'class': 'cbi-section'
+ 'class': 'cbi-section',
+ 'data-tab': this.map.tabbed ? this.sectiontype : null,
+ 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null
});
if (this.title != null && this.title != '')
if (this.addremove) {
sectionEl.appendChild(
E('div', { 'class': 'cbi-section-remove right' },
- E('input', {
- 'type': 'submit',
+ E('button', {
'class': 'cbi-button',
'name': 'cbi.rts.%s.%s'.format(config_name, cfgsections[i]),
- 'value': _('Delete'),
'data-section-id': cfgsections[i],
- 'click': L.bind(this.handleRemove, this, cfgsections[i])
- })));
+ 'click': L.ui.createHandlerFn(this, 'handleRemove', cfgsections[i])
+ }, _('Delete'))));
}
if (!this.anonymous)
sectionEl.appendChild(E('div', {
'id': 'cbi-%s-%s'.format(config_name, cfgsections[i]),
'class': this.tabs
- ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node'
+ ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node',
+ 'data-section-id': cfgsections[i]
}, nodes[i]));
-
- if (this.tabs)
- ui.tabs.initTabGroup(sectionEl.lastChild.childNodes);
}
if (nodes.length == 0)
- L.dom.append(sectionEl, [
- E('em', _('This section contains no values yet')),
- E('br'), E('br')
- ]);
+ sectionEl.appendChild(this.renderSectionPlaceholder());
sectionEl.appendChild(this.renderSectionAdd());
has_more = max_cols < this.children.length,
sectionEl = E('div', {
'id': 'cbi-%s-%s'.format(config_name, this.sectiontype),
- 'class': 'cbi-section cbi-tblsection'
+ 'class': 'cbi-section cbi-tblsection',
+ 'data-tab': this.map.tabbed ? this.sectiontype : null,
+ 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null
}),
tableEl = E('div', {
'class': 'table cbi-section-table'
tableEl.appendChild(this.renderHeaderRows(max_cols));
for (var i = 0; i < nodes.length; i++) {
- var sectionname = this.stripTags((typeof(this.sectiontitle) == 'function')
- ? String(this.sectiontitle(cfgsections[i]) || '') : cfgsections[i]).trim();
+ var sectionname = this.titleFn('sectiontitle', cfgsections[i]);
var trEl = E('div', {
'id': 'cbi-%s-%s'.format(config_name, cfgsections[i]),
'dragleave': this.sortable ? L.bind(this.handleDragLeave, this) : null,
'dragend': this.sortable ? L.bind(this.handleDragEnd, this) : null,
'drop': this.sortable ? L.bind(this.handleDrop, this) : null,
- 'data-title': (sectionname && (!this.anonymous || this.sectiontitle)) ? sectionname : null
+ 'data-title': (sectionname && (!this.anonymous || this.sectiontitle)) ? sectionname : null,
+ 'data-section-id': cfgsections[i]
});
if (this.extedit || this.rowcolors)
}
if (this.addremove) {
+ var btn_title = this.titleFn('removebtntitle', section_id);
+
L.dom.append(tdEl.lastElementChild,
E('input', {
'type': 'submit',
- 'value': _('Delete'),
- 'title': _('Delete'),
+ 'value': btn_title || _('Delete'),
+ 'title': btn_title || _('Delete'),
'class': 'cbi-button cbi-button-remove',
'click': L.bind(function(sid, ev) {
uci.remove(config_name, sid);
- this.map.save();
+ this.map.save(null, true);
}, this, section_id)
})
);
name = null,
m = new CBIMap(this.map.config, null, null),
s = m.section(CBINamedSection, section_id, this.sectiontype);
- s.tabs = this.tabs;
- s.tab_names = this.tab_names;
- if (typeof(this.sectiontitle) == 'function')
- name = this.stripTags(String(this.sectiontitle(section_id) || ''));
- else if (!this.anonymous)
- name = section_id;
+ s.tabs = this.tabs;
+ s.tab_names = this.tab_names;
- if (name)
- title += ' - ' + name;
+ if ((name = this.titleFn('modaltitle', section_id)) != null)
+ title = name;
+ else if ((name = this.titleFn('sectiontitle', section_id)) != null)
+ title = '%s - %s'.format(parent.title, name);
+ else if (!this.anonymous)
+ title = '%s - %s'.format(parent.title, section_id);
for (var i = 0; i < this.children.length; i++) {
var o1 = this.children[i];
}
}
- //ev.target.classList.add('spinning');
Promise.resolve(this.addModalOptions(s, section_id, ev)).then(L.bind(m.render, m)).then(L.bind(function(nodes) {
- //ev.target.classList.remove('spinning');
L.ui.showModal(title, [
nodes,
E('div', { 'class': 'right' }, [
- E('input', {
- 'type': 'button',
+ E('button', {
'class': 'btn',
- 'click': L.bind(this.handleModalCancel, this, m),
- 'value': _('Dismiss')
- }), ' ',
- E('input', {
- 'type': 'button',
+ 'click': L.ui.createHandlerFn(this, 'handleModalCancel', m)
+ }, _('Dismiss')), ' ',
+ E('button', {
'class': 'cbi-button cbi-button-positive important',
- 'click': L.bind(this.handleModalSave, this, m),
- 'value': _('Save')
- })
+ 'click': L.ui.createHandlerFn(this, 'handleModalSave', m)
+ }, _('Save'))
])
], 'cbi-modal');
}, this)).catch(L.error);
config_name = this.uciconfig || this.map.config;
uci.add(config_name, this.sectiontype, section_id);
- this.map.save();
+ return this.map.save(null, true);
},
handleRemove: function(ev) {
config_name = this.uciconfig || this.map.config;
uci.remove(config_name, section_id);
- this.map.save();
+ return this.map.save(null, true);
},
renderContents: function(data) {
config_name = this.uciconfig || this.map.config,
sectionEl = E('div', {
'id': ucidata ? null : 'cbi-%s-%s'.format(config_name, section_id),
- 'class': 'cbi-section'
+ 'class': 'cbi-section',
+ 'data-tab': this.map.tabbed ? this.sectiontype : null,
+ 'data-tab-title': this.map.tabbed ? this.title || this.sectiontype : null
});
if (typeof(this.title) === 'string' && this.title !== '')
if (this.addremove) {
sectionEl.appendChild(
E('div', { 'class': 'cbi-section-remove right' },
- E('input', {
- 'type': 'submit',
+ E('button', {
'class': 'cbi-button',
- 'value': _('Delete'),
- 'click': L.bind(this.handleRemove, this)
- })));
+ 'click': L.ui.createHandlerFn(this, 'handleRemove')
+ }, _('Delete'))));
}
sectionEl.appendChild(E('div', {
'id': 'cbi-%s-%s'.format(config_name, section_id),
'class': this.tabs
- ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node'
+ ? 'cbi-section-node cbi-section-node-tabbed' : 'cbi-section-node',
+ 'data-section-id': section_id
}, nodes));
-
- if (this.tabs)
- ui.tabs.initTabGroup(sectionEl.lastChild.childNodes);
}
else if (this.addremove) {
sectionEl.appendChild(
- E('input', {
- 'type': 'submit',
+ E('button', {
'class': 'cbi-button cbi-button-add',
- 'value': _('Add'),
- 'click': L.bind(this.handleAdd, this)
- }));
+ 'click': L.ui.createHandlerFn(this, 'handleAdd')
+ }, _('Add')));
}
L.dom.bindClassInstance(sectionEl, this);
},
renderFrame: function(section_id, in_table, option_index, nodes) {
- var config_name = this.uciconfig || this.map.config,
+ var config_name = this.uciconfig || this.section.uciconfig || this.map.config,
depend_list = this.transformDepList(section_id),
optionEl;
},
});
+var CBITextValue = CBIValue.extend({
+ __name__: 'CBI.TextValue',
+
+ value: null,
+
+ renderWidget: function(section_id, option_index, cfgvalue) {
+ var value = (cfgvalue != null) ? cfgvalue : this.default;
+
+ var widget = new ui.Textarea(value, {
+ id: this.cbid(section_id),
+ optional: this.optional || this.rmempty,
+ placeholder: this.placeholder,
+ monospace: this.monospace,
+ cols: this.cols,
+ rows: this.rows,
+ wrap: this.wrap,
+ validate: L.bind(this.validate, this, section_id)
+ });
+
+ return widget.render();
+ }
+});
+
var CBIDummyValue = CBIValue.extend({
__name__: 'CBI.DummyValue',
hiddenEl.render()
]);
},
+
+ remove: function() {},
+ write: function() {}
});
var CBIButtonValue = CBIValue.extend({
__name__: 'CBI.ButtonValue',
renderWidget: function(section_id, option_index, cfgvalue) {
- var value = (cfgvalue != null) ? cfgvalue : this.default;
+ var value = (cfgvalue != null) ? cfgvalue : this.default,
+ hiddenEl = new ui.Hiddenfield(value, { id: this.cbid(section_id) }),
+ outputEl = E('div'),
+ btn_title = this.titleFn('inputtitle', section_id) || this.titleFn('title', section_id);
if (value !== false)
- return E([
- E('input', {
- 'type': 'hidden',
- 'id': this.cbid(section_id)
- }),
+ L.dom.content(outputEl, [
E('input', {
'class': 'cbi-button cbi-button-%s'.format(this.inputstyle || 'button'),
- 'type': 'submit',
- //'id': this.cbid(section_id),
- //'name': this.cbid(section_id),
- 'value': this.inputtitle || this.title,
- 'click': L.bind(function(ev) {
+ 'type': 'button',
+ 'value': btn_title,
+ 'click': L.bind(this.onclick || function(ev) {
ev.target.previousElementSibling.value = ev.target.value;
this.map.save();
}, this)
})
]);
else
- return document.createTextNode(' - ');
+ L.dom.content(outputEl, ' - ');
+
+ return E([
+ outputEl,
+ hiddenEl.render()
+ ]);
}
});
checkDepends: function(section_id) {
this.subsection.checkDepends();
- return this.super('checkDepends');
+ return CBIValue.prototype.checkDepends.apply(this, [ section_id ]);
},
write: function() {},
ListValue: CBIListValue,
Flag: CBIFlagValue,
MultiValue: CBIMultiValue,
+ TextValue: CBITextValue,
DummyValue: CBIDummyValue,
Button: CBIButtonValue,
HiddenValue: CBIHiddenValue,