VENOM-10: added, fake tables with display:grid. create v-table as html dom element
This commit is contained in:
parent
162cc4b0a4
commit
9519236662
7 changed files with 638 additions and 95 deletions
|
|
@ -196,6 +196,193 @@ class VRipple {
|
|||
}
|
||||
}
|
||||
const rippler = new VRipple();
|
||||
|
||||
|
||||
|
||||
(function () {
|
||||
window._openVSelect = null;
|
||||
|
||||
requestAnimationFrame(e => {
|
||||
document.body.addEventListener('click', ev => {
|
||||
if (window._openVSelect && ev.target.closest('v-select') !== window._openVSelect) {
|
||||
window._openVSelect.toggle(false);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
class VSelectElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
let self = this;
|
||||
self._in = this.attachInternals();
|
||||
self._in.role = 'select';
|
||||
self.setAttribute('tabindex', 0);
|
||||
self.update();
|
||||
}
|
||||
|
||||
static get formAssociated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['required', 'validity'];
|
||||
}
|
||||
|
||||
get required() {
|
||||
return this.hasAttribute('required');
|
||||
}
|
||||
|
||||
set required(flag) {
|
||||
this.toggleAttribute('required', Boolean(flag));
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.getAttribute('name');
|
||||
}
|
||||
|
||||
set name(val) {
|
||||
this.toggleAttribute('name', val);
|
||||
}
|
||||
|
||||
get form() {
|
||||
return this._in.form;
|
||||
}
|
||||
|
||||
get options() {
|
||||
return $$('v-options v-option', this);
|
||||
}
|
||||
|
||||
get selected() {
|
||||
return $$('v-options v-option[selected]', this);
|
||||
}
|
||||
|
||||
update() {
|
||||
let selected = [],
|
||||
lbl = $('v-label', this),
|
||||
fd = new FormData();
|
||||
this.selected.forEach(e => {
|
||||
selected.push(e.innerText);
|
||||
fd.append(this.name, e.value);
|
||||
})
|
||||
lbl.attributeChangedCallback('value', '', selected.join(", "));
|
||||
if (this.required && selected.length === 0) {
|
||||
this._in.setValidity({customError: true}, "Option is needed");
|
||||
} else {
|
||||
this._in.setValidity({});
|
||||
}
|
||||
this._in.setFormValue(fd);
|
||||
}
|
||||
|
||||
checkValidity() {
|
||||
return this._in.checkValidity();
|
||||
}
|
||||
|
||||
reportValidity() {
|
||||
return this._in.reportValidity();
|
||||
}
|
||||
|
||||
toggle(open) {
|
||||
if (window._openVSelect && open) {
|
||||
window._openVSelect.toggleSelect(false);
|
||||
}
|
||||
const options = $('v-options', this);
|
||||
if (!open || this.isOpen) {
|
||||
options.style.maxHeight = '0';
|
||||
window._openVSelect = false;
|
||||
this.isOpen = false;
|
||||
this.update();
|
||||
} else {
|
||||
options.focus();
|
||||
let height = 0,
|
||||
children = options.children;
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
height += children[i].offsetHeight;
|
||||
}
|
||||
options.style.maxHeight = height + 'px';
|
||||
window._openVSelect = this;
|
||||
this.isOpen = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class VSelectOptionElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this._in = this.attachInternals();
|
||||
this._in.role = 'option';
|
||||
this.addEventListener('click', e => {
|
||||
let parent = this.parentNode.parentNode,
|
||||
select = !this.selected;
|
||||
if (!parent.hasAttribute('multiple')) {
|
||||
parent.toggle(false);
|
||||
for (let item of parent.selected) {
|
||||
if (item !== this) {
|
||||
item.removeAttribute('selected');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!this.disabled) {
|
||||
this.attributeChangedCallback('selected', false, select, true);
|
||||
this.parentNode.parentNode.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['selected', 'disabled', 'value'];
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue, force) {
|
||||
if (name === 'selected' && this.hasAttribute('disabled')) {
|
||||
this.removeAttribute(name);
|
||||
return;
|
||||
}
|
||||
if (name === 'disabled' && newValue === true && this.hasAttribute('selected')) {
|
||||
this.attributeChangedCallback('selected', false, false);
|
||||
}
|
||||
|
||||
if (force) {
|
||||
if (newValue) {
|
||||
this.setAttribute(name, newValue);
|
||||
} else {
|
||||
this.removeAttribute(name);
|
||||
}
|
||||
}
|
||||
this[name] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
class VLabel extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.empty = this.getAttribute('empty') || "";
|
||||
this.innerHTML = this.getAttribute("value") || this.empty;
|
||||
this.addEventListener('click', this.openPopUp.bind(this));
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ['empty', 'value'];
|
||||
}
|
||||
|
||||
openPopUp() {
|
||||
this.parentNode.toggle(true);
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (name === 'value') {
|
||||
this.innerHTML = newValue || this.empty;
|
||||
}
|
||||
this[name] = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("v-label", VLabel);
|
||||
customElements.define("v-option", VSelectOptionElement);
|
||||
customElements.define("v-select", VSelectElement);
|
||||
})();
|
||||
|
||||
|
||||
|
||||
class FormHandler {
|
||||
constructor(selector, parent, cb, err) {
|
||||
this.cb = cb || console.log;
|
||||
|
|
@ -263,4 +450,4 @@ class FormHandler {
|
|||
$('.error-message', el).classList.remove('hide');
|
||||
})
|
||||
}
|
||||
})()
|
||||
})();
|
||||
2
public/theme/admin/js/scripts.min.js
vendored
2
public/theme/admin/js/scripts.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue