luci-base, themes: rework dynlist and dropdown widgets
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
This commit is contained in:
parent
bd614de514
commit
7c78218339
4 changed files with 358 additions and 310 deletions
|
@ -794,95 +794,41 @@ function cbi_init() {
|
|||
cbi_d_update();
|
||||
}
|
||||
|
||||
function cbi_combobox(id, values, def, man, focus) {
|
||||
var selid = "cbi.combobox." + id;
|
||||
if (document.getElementById(selid)) {
|
||||
return
|
||||
}
|
||||
function cbi_combobox_init(id, values, def, man) {
|
||||
var obj = (typeof(id) === 'string') ? document.getElementById(id) : id;
|
||||
var sb = E('div', {
|
||||
'name': obj.name,
|
||||
'class': 'cbi-dropdown',
|
||||
'display-items': 5,
|
||||
'optional': obj.getAttribute('data-optional'),
|
||||
'placeholder': _('-- Please choose --')
|
||||
}, [ E('ul') ]);
|
||||
|
||||
var obj = document.getElementById(id)
|
||||
var sel = document.createElement("select");
|
||||
sel.id = selid;
|
||||
sel.index = obj.index;
|
||||
sel.classList.remove('cbi-input-text');
|
||||
sel.classList.add('cbi-input-select');
|
||||
|
||||
if (obj.nextSibling)
|
||||
obj.parentNode.insertBefore(sel, obj.nextSibling);
|
||||
else
|
||||
obj.parentNode.appendChild(sel);
|
||||
|
||||
var dt = obj.getAttribute('cbi_datatype');
|
||||
var op = obj.getAttribute('cbi_optional');
|
||||
|
||||
if (!values[obj.value]) {
|
||||
if (obj.value == "") {
|
||||
var optdef = document.createElement("option");
|
||||
optdef.value = "";
|
||||
optdef.appendChild(document.createTextNode(typeof(def) === 'string' ? def : _('-- Please choose --')));
|
||||
sel.appendChild(optdef);
|
||||
}
|
||||
else {
|
||||
var opt = document.createElement("option");
|
||||
opt.value = obj.value;
|
||||
opt.selected = "selected";
|
||||
opt.appendChild(document.createTextNode(obj.value));
|
||||
sel.appendChild(opt);
|
||||
}
|
||||
if (!(obj.value in values) && obj.value.length) {
|
||||
sb.lastElementChild.appendChild(E('li', {
|
||||
'data-value': obj.value,
|
||||
'selected': ''
|
||||
}, obj.value.length ? obj.value : (def || _('-- Please choose --'))));
|
||||
}
|
||||
|
||||
for (var i in values) {
|
||||
var opt = document.createElement("option");
|
||||
opt.value = i;
|
||||
|
||||
if (obj.value == i)
|
||||
opt.selected = "selected";
|
||||
|
||||
opt.appendChild(document.createTextNode(values[i]));
|
||||
sel.appendChild(opt);
|
||||
sb.lastElementChild.appendChild(E('li', {
|
||||
'data-value': i,
|
||||
'selected': (i == obj.value) ? '' : null
|
||||
}, values[i]));
|
||||
}
|
||||
|
||||
var optman = document.createElement("option");
|
||||
optman.value = "";
|
||||
optman.appendChild(document.createTextNode(typeof(man) === 'string' ? man : _('-- custom --')));
|
||||
sel.appendChild(optman);
|
||||
sb.lastElementChild.appendChild(E('li', { 'data-value': '-' }, [
|
||||
E('input', {
|
||||
'type': 'text',
|
||||
'class': 'create-item-input',
|
||||
'data-type': obj.getAttribute('data-type'),
|
||||
'data-optional': true,
|
||||
'placeholder': (man || _('-- custom --'))
|
||||
})
|
||||
]));
|
||||
|
||||
obj.style.display = "none";
|
||||
|
||||
if (dt)
|
||||
cbi_validate_field(sel, op == 'true', dt);
|
||||
|
||||
sel.addEventListener("change", function() {
|
||||
if (sel.selectedIndex == sel.options.length - 1) {
|
||||
obj.style.display = "inline";
|
||||
sel.blur();
|
||||
sel.parentNode.removeChild(sel);
|
||||
obj.focus();
|
||||
}
|
||||
else {
|
||||
obj.value = sel.options[sel.selectedIndex].value;
|
||||
}
|
||||
|
||||
try {
|
||||
cbi_d_update();
|
||||
} catch (e) {
|
||||
//Do nothing
|
||||
}
|
||||
})
|
||||
|
||||
// Retrigger validation in select
|
||||
if (focus) {
|
||||
sel.focus();
|
||||
sel.blur();
|
||||
}
|
||||
}
|
||||
|
||||
function cbi_combobox_init(id, values, def, man) {
|
||||
var obj = (typeof(id) === 'string') ? document.getElementById(id) : id;
|
||||
obj.addEventListener("blur", function() {
|
||||
cbi_combobox(obj.id, values, def, man, true);
|
||||
});
|
||||
cbi_combobox(obj.id, values, def, man, false);
|
||||
obj.parentNode.replaceChild(sb, obj);
|
||||
}
|
||||
|
||||
function cbi_filebrowser(id, defpath) {
|
||||
|
@ -912,229 +858,151 @@ function cbi_browser_init(id, resource, defpath)
|
|||
btn.addEventListener('click', cbi_browser_btnclick);
|
||||
}
|
||||
|
||||
function cbi_dynlist_init(parent, datatype, optional, choices)
|
||||
CBIDynamicList = {
|
||||
addItem: function(dl, value, text, flash) {
|
||||
var exists = false,
|
||||
new_item = E('div', { 'class': flash ? 'item flash' : 'item', 'tabindex': 0 }, [
|
||||
E('span', {}, text || value),
|
||||
E('input', {
|
||||
'type': 'hidden',
|
||||
'name': dl.getAttribute('data-prefix'),
|
||||
'value': value })]);
|
||||
|
||||
dl.querySelectorAll('.item, .add-item').forEach(function(item) {
|
||||
if (exists)
|
||||
return;
|
||||
|
||||
var hidden = item.querySelector('input[type="hidden"]');
|
||||
|
||||
if (hidden && hidden.value === value)
|
||||
exists = true;
|
||||
else if (!hidden || hidden.value >= value)
|
||||
exists = !!item.parentNode.insertBefore(new_item, item);
|
||||
});
|
||||
},
|
||||
|
||||
removeItem: function(dl, item) {
|
||||
var sb = dl.querySelector('.cbi-dropdown');
|
||||
if (sb) {
|
||||
var value = item.querySelector('input[type="hidden"]').value;
|
||||
|
||||
sb.querySelectorAll('ul > li').forEach(function(li) {
|
||||
if (li.getAttribute('data-value') === value)
|
||||
li.removeAttribute('unselectable');
|
||||
});
|
||||
}
|
||||
|
||||
item.parentNode.removeChild(item);
|
||||
},
|
||||
|
||||
handleClick: function(ev) {
|
||||
var dl = ev.currentTarget,
|
||||
item = findParent(ev.target, '.item');
|
||||
|
||||
if (item) {
|
||||
this.removeItem(dl, item);
|
||||
}
|
||||
else if (matchesElem(ev.target, '.cbi-button-add')) {
|
||||
var input = ev.target.previousElementSibling;
|
||||
if (input.value.length && !input.classList.contains('cbi-input-invalid')) {
|
||||
this.addItem(dl, input.value, null, true);
|
||||
input.value = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleDropdownChange: function(ev) {
|
||||
var dl = ev.currentTarget,
|
||||
sbIn = ev.detail.instance,
|
||||
sbEl = ev.detail.element,
|
||||
sbVal = ev.detail.value;
|
||||
|
||||
if (sbVal === null)
|
||||
return;
|
||||
|
||||
sbIn.setValues(sbEl, null);
|
||||
sbVal.element.setAttribute('unselectable', '');
|
||||
|
||||
this.addItem(dl, sbVal.value, sbVal.text, true);
|
||||
},
|
||||
|
||||
handleKeydown: function(ev) {
|
||||
var dl = ev.currentTarget,
|
||||
item = findParent(ev.target, '.item');
|
||||
|
||||
if (item) {
|
||||
switch (ev.keyCode) {
|
||||
case 8: /* backspace */
|
||||
if (item.previousElementSibling)
|
||||
item.previousElementSibling.focus();
|
||||
|
||||
this.removeItem(dl, item);
|
||||
break;
|
||||
|
||||
case 46: /* delete */
|
||||
if (item.nextElementSibling) {
|
||||
if (item.nextElementSibling.classList.contains('item'))
|
||||
item.nextElementSibling.focus();
|
||||
else
|
||||
item.nextElementSibling.firstElementChild.focus();
|
||||
}
|
||||
|
||||
this.removeItem(dl, item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (matchesElem(ev.target, '.cbi-input-text')) {
|
||||
switch (ev.keyCode) {
|
||||
case 13: /* enter */
|
||||
if (ev.target.value.length && !ev.target.classList.contains('cbi-input-invalid')) {
|
||||
this.addItem(dl, ev.target.value, null, true);
|
||||
ev.target.value = '';
|
||||
ev.target.blur();
|
||||
ev.target.focus();
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function cbi_dynlist_init(dl, datatype, optional, choices)
|
||||
{
|
||||
var prefix = parent.getAttribute('data-prefix');
|
||||
var holder = parent.getAttribute('data-placeholder');
|
||||
if (!(this instanceof cbi_dynlist_init))
|
||||
return new cbi_dynlist_init(dl, datatype, optional, choices);
|
||||
|
||||
var values;
|
||||
dl.classList.add('cbi-dynlist');
|
||||
dl.appendChild(E('div', { 'class': 'add-item' }, E('input', {
|
||||
'type': 'text',
|
||||
'name': 'cbi.dynlist.' + dl.getAttribute('data-prefix'),
|
||||
'class': 'cbi-input-text',
|
||||
'data-type': datatype,
|
||||
'data-optional': true
|
||||
})));
|
||||
|
||||
function cbi_dynlist_redraw(focus, add, del)
|
||||
{
|
||||
values = [ ];
|
||||
if (choices)
|
||||
cbi_combobox_init(dl.lastElementChild.lastElementChild, choices, '', _('-- custom --'));
|
||||
else
|
||||
dl.lastElementChild.appendChild(E('div', { 'class': 'cbi-button cbi-button-add' }, '+'));
|
||||
|
||||
while (parent.firstChild) {
|
||||
var n = parent.firstChild;
|
||||
var i = +n.index;
|
||||
dl.addEventListener('click', this.handleClick.bind(this));
|
||||
dl.addEventListener('keydown', this.handleKeydown.bind(this));
|
||||
dl.addEventListener('cbi-dropdown-change', this.handleDropdownChange.bind(this));
|
||||
|
||||
if (i != del) {
|
||||
if (matchesElem(n, 'input'))
|
||||
values.push(n.value || '');
|
||||
else if (matchesElem(n, 'select'))
|
||||
values[values.length-1] = n.options[n.selectedIndex].value;
|
||||
}
|
||||
try {
|
||||
var values = JSON.parse(dl.getAttribute('data-values') || '[]');
|
||||
|
||||
parent.removeChild(n);
|
||||
}
|
||||
|
||||
if (add >= 0) {
|
||||
focus = add+1;
|
||||
values.splice(focus, 0, '');
|
||||
}
|
||||
else if (values.length == 0) {
|
||||
focus = 0;
|
||||
values.push('');
|
||||
}
|
||||
|
||||
for (var i = 0; i < values.length; i++) {
|
||||
var t = document.createElement('input');
|
||||
t.id = prefix + '.' + (i+1);
|
||||
t.name = prefix;
|
||||
t.value = values[i];
|
||||
t.type = 'text';
|
||||
t.index = i;
|
||||
t.className = 'cbi-input-text';
|
||||
|
||||
if (i == 0 && holder)
|
||||
t.placeholder = holder;
|
||||
|
||||
var b = E('div', {
|
||||
class: 'cbi-button cbi-button-' + ((i+1) < values.length ? 'remove' : 'add')
|
||||
}, (i+1) < values.length ? '×' : '+');
|
||||
|
||||
parent.appendChild(t);
|
||||
parent.appendChild(b);
|
||||
|
||||
if (datatype == 'file')
|
||||
cbi_browser_init(t.id, null, parent.getAttribute('data-browser-path'));
|
||||
|
||||
parent.appendChild(document.createElement('br'));
|
||||
|
||||
if (datatype)
|
||||
cbi_validate_field(t.id, ((i+1) == values.length) || optional, datatype);
|
||||
|
||||
if (choices) {
|
||||
cbi_combobox_init(t.id, choices, '', _('-- custom --'));
|
||||
b.index = i;
|
||||
|
||||
b.addEventListener('keydown', cbi_dynlist_keydown);
|
||||
b.addEventListener('keypress', cbi_dynlist_keypress);
|
||||
|
||||
if (i == focus || -i == focus)
|
||||
b.focus();
|
||||
}
|
||||
else {
|
||||
t.addEventListener('keydown', cbi_dynlist_keydown);
|
||||
t.addEventListener('keypress', cbi_dynlist_keypress);
|
||||
|
||||
if (i == focus) {
|
||||
t.focus();
|
||||
}
|
||||
else if (-i == focus) {
|
||||
t.focus();
|
||||
|
||||
/* force cursor to end */
|
||||
var v = t.value;
|
||||
t.value = ' '
|
||||
t.value = v;
|
||||
}
|
||||
}
|
||||
|
||||
b.addEventListener('click', cbi_dynlist_btnclick);
|
||||
}
|
||||
if (typeof(values) === 'object' && Array.isArray(values))
|
||||
for (var i = 0; i < values.length; i++)
|
||||
this.addItem(dl, values[i], choices ? choices[values[i]] : null);
|
||||
}
|
||||
|
||||
function cbi_dynlist_keypress(ev)
|
||||
{
|
||||
ev = ev ? ev : window.event;
|
||||
|
||||
var se = ev.target ? ev.target : ev.srcElement;
|
||||
|
||||
if (se.nodeType == 3)
|
||||
se = se.parentNode;
|
||||
|
||||
switch (ev.keyCode) {
|
||||
/* backspace, delete */
|
||||
case 8:
|
||||
case 46:
|
||||
if (se.value.length == 0) {
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
/* enter, arrow up, arrow down */
|
||||
case 13:
|
||||
case 38:
|
||||
case 40:
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function cbi_dynlist_keydown(ev)
|
||||
{
|
||||
ev = ev ? ev : window.event;
|
||||
|
||||
var se = ev.target ? ev.target : ev.srcElement;
|
||||
|
||||
if (se.nodeType == 3)
|
||||
se = se.parentNode;
|
||||
|
||||
var prev = se.previousSibling;
|
||||
while (prev && prev.name != prefix)
|
||||
prev = prev.previousSibling;
|
||||
|
||||
var next = se.nextSibling;
|
||||
while (next && next.name != prefix)
|
||||
next = next.nextSibling;
|
||||
|
||||
/* advance one further in combobox case */
|
||||
if (next && next.nextSibling.name == prefix)
|
||||
next = next.nextSibling;
|
||||
|
||||
switch (ev.keyCode) {
|
||||
/* backspace, delete */
|
||||
case 8:
|
||||
case 46:
|
||||
var del = (matchesElem(se, 'select'))
|
||||
? true : (se.value.length == 0);
|
||||
|
||||
if (del) {
|
||||
if (ev.preventDefault)
|
||||
ev.preventDefault();
|
||||
|
||||
var focus = se.index;
|
||||
if (ev.keyCode == 8)
|
||||
focus = -focus+1;
|
||||
|
||||
cbi_dynlist_redraw(focus, -1, se.index);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
/* enter */
|
||||
case 13:
|
||||
cbi_dynlist_redraw(-1, se.index, -1);
|
||||
break;
|
||||
|
||||
/* arrow up */
|
||||
case 38:
|
||||
if (prev)
|
||||
prev.focus();
|
||||
|
||||
break;
|
||||
|
||||
/* arrow down */
|
||||
case 40:
|
||||
if (next)
|
||||
next.focus();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function cbi_dynlist_btnclick(ev)
|
||||
{
|
||||
ev = ev ? ev : window.event;
|
||||
|
||||
var se = ev.target ? ev.target : ev.srcElement;
|
||||
var input = se.previousSibling;
|
||||
while (input && input.name != prefix)
|
||||
input = input.previousSibling;
|
||||
|
||||
if (se.classList.contains('cbi-button-remove')) {
|
||||
input.value = '';
|
||||
|
||||
cbi_dynlist_keydown({
|
||||
target: input,
|
||||
keyCode: 8
|
||||
});
|
||||
}
|
||||
else {
|
||||
cbi_dynlist_keydown({
|
||||
target: input,
|
||||
keyCode: 13
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
cbi_dynlist_redraw(NaN, -1, -1);
|
||||
catch (e) {}
|
||||
}
|
||||
|
||||
cbi_dynlist_init.prototype = CBIDynamicList;
|
||||
|
||||
|
||||
function cbi_t_add(section, tab) {
|
||||
var t = document.getElementById('tab.' + section + '.' + tab);
|
||||
|
|
|
@ -492,12 +492,47 @@ select,
|
|||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cbi-dropdown {
|
||||
.cbi-dropdown,
|
||||
.cbi-dynlist {
|
||||
min-width: 210px;
|
||||
max-width: 400px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.cbi-dynlist {
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item {
|
||||
margin-bottom: 4px;
|
||||
box-shadow: 0 0 2px #ccc;
|
||||
background: #fff;
|
||||
padding: 2px 2em 2px 4px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item::after {
|
||||
content: "×";
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
padding: 0 6px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0 3px 3px 0;
|
||||
font-weight: bold;
|
||||
color: #c44;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
select {
|
||||
padding: initial;
|
||||
background: #fff;
|
||||
|
@ -548,7 +583,8 @@ textarea {
|
|||
.td > input[type=text],
|
||||
.td > input[type=password],
|
||||
.td > select,
|
||||
.td > .cbi-dropdown {
|
||||
.td > .cbi-dropdown,
|
||||
.cbi-dynlist > .add-item > .cbi-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
@ -568,11 +604,12 @@ textarea {
|
|||
color: #bfbfbf;
|
||||
}
|
||||
|
||||
.btn, .cbi-button, input, textarea {
|
||||
.item::after, .btn, .cbi-button, input, textarea {
|
||||
transition: border linear 0.2s, box-shadow linear 0.2s;
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.item:hover::after,
|
||||
.btn:hover, .cbi-button:hover,
|
||||
input:focus, textarea:focus {
|
||||
outline: 0;
|
||||
|
@ -1206,6 +1243,7 @@ footer {
|
|||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
.item::after,
|
||||
.btn,
|
||||
.cbi-button {
|
||||
cursor: pointer;
|
||||
|
@ -1318,6 +1356,7 @@ footer {
|
|||
color: #404040;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item:focus,
|
||||
.cbi-dropdown:focus {
|
||||
outline: 2px solid #4b6e9b;
|
||||
}
|
||||
|
@ -1354,6 +1393,7 @@ footer {
|
|||
font-weight: bold;
|
||||
text-shadow: 1px 1px 0px #fff;
|
||||
display: none;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul > li {
|
||||
|
@ -1454,6 +1494,14 @@ footer {
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cbi-dropdown[disabled] {
|
||||
pointer-events: none;
|
||||
opacity: .6;
|
||||
|
|
|
@ -153,7 +153,9 @@ input,
|
|||
}
|
||||
|
||||
select:not([multiple="multiple"]):focus,
|
||||
input:focus {
|
||||
input:focus,
|
||||
.cbi-dropdown:focus,
|
||||
.cbi-dynlist > .item:focus {
|
||||
border-color: var(--main-color, #0099CC);
|
||||
}
|
||||
|
||||
|
@ -642,7 +644,7 @@ td > table > tbody > tr > td,
|
|||
|
||||
/* button style */
|
||||
|
||||
.btn, .cbi-button {
|
||||
.btn, .cbi-button, .item::after {
|
||||
-webkit-appearance: none;
|
||||
text-transform: uppercase;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
|
@ -675,6 +677,7 @@ td > table > tbody > tr > td,
|
|||
.cbi-button:hover,
|
||||
.cbi-button:focus,
|
||||
.cbi-button:active,
|
||||
.item:hover::after,
|
||||
.cbi-page-actions .cbi-button-apply + .cbi-button-save:hover,
|
||||
.cbi-page-actions .cbi-button-apply + .cbi-button-save:focus,
|
||||
.cbi-page-actions .cbi-button-apply + .cbi-button-save:active {
|
||||
|
@ -958,6 +961,7 @@ td > table > tbody > tr > td,
|
|||
}
|
||||
|
||||
|
||||
.cbi-dynlist,
|
||||
.cbi-dropdown {
|
||||
display: inline-flex;
|
||||
cursor: pointer;
|
||||
|
@ -966,10 +970,6 @@ td > table > tbody > tr > td,
|
|||
height: auto;
|
||||
}
|
||||
|
||||
.cbi-dropdown:focus {
|
||||
outline: 2px solid #4b6e9b;
|
||||
}
|
||||
|
||||
.cbi-dropdown > ul {
|
||||
margin: 0 !important;
|
||||
padding: 0;
|
||||
|
@ -1109,6 +1109,22 @@ td > table > tbody > tr > td,
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cbi-dropdown[disabled] {
|
||||
pointer-events: none;
|
||||
opacity: .6;
|
||||
|
@ -1122,6 +1138,68 @@ td > table > tbody > tr > td,
|
|||
width: auto;
|
||||
}
|
||||
|
||||
.cbi-dynlist {
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item {
|
||||
margin: 0 2em 4px 0;
|
||||
padding: 2px 4px;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, .26);
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item::after {
|
||||
content: "×";
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
top: 0;
|
||||
right: -2em;
|
||||
bottom: 0;
|
||||
padding: 0 6px;
|
||||
border: 1px solid #c44;
|
||||
font-weight: bold;
|
||||
color: #c44;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.cbi-dynlist {
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item {
|
||||
margin: 0 2em 4px 0;
|
||||
padding: 2px 4px;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, .26);
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item::after {
|
||||
content: "×";
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
top: 0;
|
||||
right: -2em;
|
||||
bottom: 0;
|
||||
padding: 0 6px;
|
||||
border: 1px solid #c44;
|
||||
font-weight: bold;
|
||||
color: #c44;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
|
||||
/* luci */
|
||||
|
||||
|
|
|
@ -516,7 +516,8 @@ input.cbi-input-password + img {
|
|||
|
||||
.td select,
|
||||
.td .cbi-dropdown,
|
||||
.td input[type=text] {
|
||||
.td input[type=text],
|
||||
.cbi-dynlist > .add-item > .cbi-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
@ -531,7 +532,7 @@ img.cbi-image-button {
|
|||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.btn, .cbi-button {
|
||||
.btn, .cbi-button, .item::after {
|
||||
padding: 0 .5em;
|
||||
border-radius: 3px;
|
||||
border: 1px solid #aaa;
|
||||
|
@ -545,9 +546,11 @@ img.cbi-image-button {
|
|||
font-weight: bold;
|
||||
line-height: 13pt;
|
||||
height: 16pt;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn:hover, .cbi-button:hover {
|
||||
.btn:hover, .cbi-button:hover, .item:hover::after {
|
||||
box-shadow: 0 0 3px #37c;
|
||||
}
|
||||
|
||||
|
@ -1009,7 +1012,8 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
background: #fff;
|
||||
}
|
||||
|
||||
.cbi-dropdown:focus {
|
||||
.cbi-dropdown:focus,
|
||||
.cbi-dynlist > .item:focus {
|
||||
outline: 2px solid #4b6e9b;
|
||||
}
|
||||
|
||||
|
@ -1150,11 +1154,60 @@ ul.cbi-tabmenu li.cbi-tab {
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li[unselectable] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.cbi-dropdown[open] > ul.dropdown > li > input.create-item-input:first-child:last-child {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cbi-dropdown[disabled] {
|
||||
pointer-events: none;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.cbi-dynlist {
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
min-width: 210px;
|
||||
max-width: 100%;
|
||||
width: auto;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item {
|
||||
margin-bottom: 4px;
|
||||
background: #eee;
|
||||
padding: 2px 2em 2px 4px;
|
||||
border: 1px outset #000;
|
||||
border-radius: 3px;
|
||||
position: relative;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.cbi-dynlist > .item::after {
|
||||
content: "×";
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
padding: 0 6px;
|
||||
border: 1px outset #000;
|
||||
background: #fff;
|
||||
border-radius: 0 3px 3px 0;
|
||||
font-weight: bold;
|
||||
color: #c44;
|
||||
pointer-events: auto;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
input[type="text"] + .cbi-button,
|
||||
input[type="password"] + .cbi-button,
|
||||
select + .cbi-button {
|
||||
|
@ -1695,13 +1748,14 @@ select + .cbi-button {
|
|||
height: 1.4em;
|
||||
}
|
||||
|
||||
[data-dynlist] > input,
|
||||
input.cbi-input-password {
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.cbi-dynlist,
|
||||
.cbi-dropdown {
|
||||
min-width: 100%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.btn, .cbi-button {
|
||||
|
|
Loading…
Reference in a new issue