mirror of
https://codeberg.org/icewind/ptouch-api.git
synced 2026-06-03 19:04:08 +02:00
element helper
This commit is contained in:
parent
20060fefe0
commit
0c4bbbe3e4
1 changed files with 134 additions and 75 deletions
209
web/label.js
209
web/label.js
|
|
@ -27,70 +27,122 @@ const nextElementId = () => {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef ElementSpec
|
||||
* @type {object}
|
||||
* @property {string} tag
|
||||
* @property {Object.<string, string>} props
|
||||
* @property {Object.<string, string>} attributes
|
||||
* @property {Object.<string, any>} data
|
||||
* @property {Object.<string, Function>} events
|
||||
* @property {string[]} clases
|
||||
* @property {(ElementSpec|string)[]} children
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param {string|ElementSpec} spec
|
||||
* @returns {HTMLElement|Text}
|
||||
*/
|
||||
const el = (spec) => {
|
||||
if (typeof spec === "string") {
|
||||
return document.createTextNode(spec);
|
||||
}
|
||||
let element = document.createElement(spec.tag);
|
||||
for (const [key, value] of Object.entries(spec.props || {})) {
|
||||
element[key] = value;
|
||||
}
|
||||
for (const [key, value] of Object.entries(spec.attributes || {})) {
|
||||
element.setAttribute(key, value);
|
||||
}
|
||||
for (const [key, value] of Object.entries(spec.data || {})) {
|
||||
element.dataset[key] = value;
|
||||
}
|
||||
for (const [key, value] of Object.entries(spec.events || {})) {
|
||||
element.addEventListener(key, value);
|
||||
}
|
||||
for (const c of spec.classes || []) {
|
||||
element.classList.add(c);
|
||||
}
|
||||
for (const child of spec.children || []) {
|
||||
element.appendChild(el(child));
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
const addElementControls = (row) => {
|
||||
{
|
||||
let sizeCol = document.createElement('td');
|
||||
sizeCol.classList.add('size');
|
||||
let sizeInput = document.createElement('input');
|
||||
sizeInput.addEventListener('input', render);
|
||||
sizeInput.type = "number";
|
||||
sizeInput.value = defaultFontSize.toString();
|
||||
sizeCol.appendChild(document.createTextNode("Size"))
|
||||
sizeCol.appendChild(sizeInput);
|
||||
row.appendChild(sizeCol);
|
||||
}
|
||||
row.appendChild(el({
|
||||
tag: 'td',
|
||||
classes: ['size'],
|
||||
children: ['Size', {
|
||||
tag: 'input',
|
||||
events: {input: render},
|
||||
props: {
|
||||
type: 'number',
|
||||
value: defaultFontSize.toString(),
|
||||
}
|
||||
}]
|
||||
}));
|
||||
|
||||
{
|
||||
let posCol = document.createElement('td');
|
||||
posCol.classList.add('pos');
|
||||
let posInputX = document.createElement('input');
|
||||
posInputX.addEventListener('input', render);
|
||||
posInputX.type = "number";
|
||||
posInputX.value = "0";
|
||||
posInputX.classList.add('pos_x');
|
||||
let posInputY = document.createElement('input');
|
||||
posInputY.addEventListener('input', render);
|
||||
posInputY.type = "number";
|
||||
posInputY.value = "0";
|
||||
posInputY.classList.add('pos_y');
|
||||
posCol.appendChild(document.createTextNode("Position"))
|
||||
posCol.appendChild(posInputX);
|
||||
posCol.appendChild(posInputY);
|
||||
row.appendChild(posCol);
|
||||
}
|
||||
row.appendChild(el({
|
||||
tag: 'td',
|
||||
classes: ['pos'],
|
||||
children: ['Position', {
|
||||
tag: 'input',
|
||||
events: {input: render},
|
||||
classes: ['pos_x'],
|
||||
props: {
|
||||
type: 'number',
|
||||
value: "0",
|
||||
}
|
||||
}, {
|
||||
tag: 'input',
|
||||
events: {input: render},
|
||||
classes: ['pos_y'],
|
||||
props: {
|
||||
type: 'number',
|
||||
value: "0",
|
||||
}
|
||||
}]
|
||||
}));
|
||||
|
||||
{
|
||||
let removeCol = document.createElement('td');
|
||||
removeCol.classList.add('delete');
|
||||
let removeInput = document.createElement('input');
|
||||
removeInput.type = "button";
|
||||
removeInput.value = "×";
|
||||
removeInput.addEventListener('click', removeElement);
|
||||
removeCol.appendChild(removeInput);
|
||||
row.appendChild(removeCol);
|
||||
}
|
||||
row.appendChild(el({
|
||||
tag: 'td',
|
||||
classes: ['delete'],
|
||||
children: [{
|
||||
tag: 'input',
|
||||
events: {click: removeElement},
|
||||
props: {
|
||||
type: 'button',
|
||||
value: 'x',
|
||||
}
|
||||
}]
|
||||
}));
|
||||
}
|
||||
|
||||
const addTextElement = () => {
|
||||
let id = nextElementId();
|
||||
let row = document.createElement('tr');
|
||||
row.dataset.elementId = id;
|
||||
row.dataset.type = 'text';
|
||||
|
||||
|
||||
let textCol = document.createElement('td');
|
||||
textCol.classList.add('text');
|
||||
textCol.colSpan = 2;
|
||||
let textInput = document.createElement('input');
|
||||
textInput.type = "text";
|
||||
textInput.addEventListener('input', render);
|
||||
textCol.appendChild(textInput);
|
||||
row.appendChild(textCol);
|
||||
let row = el({
|
||||
tag: 'tr',
|
||||
data: {elementId: id, type: 'text'},
|
||||
children: [{
|
||||
tag: 'td',
|
||||
classes: ['text'],
|
||||
props: {colSpan: 2},
|
||||
children: [{
|
||||
tag: 'input',
|
||||
events: {input: render},
|
||||
props: {
|
||||
type: 'text',
|
||||
focus: 'focused',
|
||||
}
|
||||
}]
|
||||
}]
|
||||
});
|
||||
|
||||
addElementControls(row);
|
||||
elementsTableBody.appendChild(row);
|
||||
|
||||
textInput.focus();
|
||||
};
|
||||
|
||||
const loadImage = (event) => {
|
||||
|
|
@ -107,29 +159,36 @@ const loadImage = (event) => {
|
|||
|
||||
const addImageElement = () => {
|
||||
let id = nextElementId();
|
||||
let row = document.createElement('tr');
|
||||
row.dataset.elementId = id;
|
||||
row.dataset.type = 'image';
|
||||
|
||||
|
||||
let imageCol = document.createElement('td');
|
||||
imageCol.classList.add('image');
|
||||
let imageInput = document.createElement('input');
|
||||
imageInput.type = 'file';
|
||||
let imageId = `image-input-${id}`;
|
||||
imageInput.id = imageId;
|
||||
imageInput.addEventListener('change', loadImage);
|
||||
let imageLabel = document.createElement('label');
|
||||
imageLabel.appendChild(document.createTextNode("Browse..."));
|
||||
imageLabel.setAttribute('for', imageId);
|
||||
let thumbCol = document.createElement('td');
|
||||
thumbCol.classList.add('preview');
|
||||
let imageThumb = document.createElement('img');
|
||||
imageCol.appendChild(imageLabel);
|
||||
imageCol.appendChild(imageInput);
|
||||
thumbCol.appendChild(imageThumb);
|
||||
row.appendChild(imageCol);
|
||||
row.appendChild(thumbCol);
|
||||
let row = el({
|
||||
tag: 'tr',
|
||||
data: {elementId: id, type: 'image'},
|
||||
children: [{
|
||||
tag: 'td',
|
||||
classes: ['image'],
|
||||
children: [{
|
||||
tag: 'input',
|
||||
events: {change: loadImage},
|
||||
props: {
|
||||
id: imageId,
|
||||
type: 'file',
|
||||
focus: 'focused',
|
||||
}
|
||||
},{
|
||||
tag: 'label',
|
||||
events: {change: loadImage},
|
||||
children: "Browse...",
|
||||
attributes: {
|
||||
for: imageId,
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
tag: 'td',
|
||||
classes: ['preview'],
|
||||
children: [{tag: 'img'}]
|
||||
}]
|
||||
});
|
||||
|
||||
addElementControls(row);
|
||||
elementsTableBody.appendChild(row);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue