You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.6 KiB
JavaScript

class TableWidget extends BaseWidget {
$el;
#align = '';
#width = '';
#data = '';
#path = '';
constructor(data, renderer) {
super(data, renderer);
this.makeLayout({
type: 'table',
class: 'w_table',
name: 'el',
});
this.update(data);
}
update(data) {
super.update(data);
if ('align' in data) this.#align = data.align;
if ('width' in data) this.#width = data.width;
if ('value' in data) {
let val = data.value;
if (!val.includes(';') && val.endsWith(".csv")) { // file
this.#path = val;
} else {
this.#path = '';
this.#data = val;
}
}
if ('action' in data || 'value' in data) this.#reload();
else if ('align' in data || 'width' in data) this.#render();
}
#reload() {
if (this.#path) {
this.$el.innerHTML = waiter();
this.addFile(this.#path, 'text', file => {
this.#data = file.replaceAll(/\\n/ig, "\n");
this.#render();
});
} else {
this.#render();
}
}
#render() {
const aligns = this.#align.split(/[,;]/);
const widths = this.#width.split(/[,;]/);
const table = parseCSV(this.#data);
const items = [];
for (const row of table) {
const $row = document.createElement('tr');
for (const col in row) {
const $col = document.createElement('td');
if (widths[col]) $col.width = widths[col] + '%';
$col.align = aligns[col] ?? 'center';
$col.textContent = row[col];
$row.append($col);
}
items.push($row);
}
this.$el.replaceChildren(...items);
}
}
function parseCSV(str) {
// https://stackoverflow.com/a/14991797
const arr = [];
let quote = false;
for (let row = 0, col = 0, c = 0; c < str.length; c++) {
let cc = str[c], nc = str[c + 1];
arr[row] = arr[row] || [];
arr[row][col] = arr[row][col] || '';
if (cc == '"' && quote && nc == '"') { arr[row][col] += cc; ++c; continue; }
if (cc == '"') { quote = !quote; continue; }
if ((cc == ';' || cc == ',' ) && !quote) { ++col; continue; }
if (cc == '\r' && nc == '\n' && !quote) { ++row; col = 0; ++c; continue; }
if (cc == '\n' && !quote) { ++row; col = 0; continue; }
if (cc == '\r' && !quote) { ++row; col = 0; continue; }
arr[row][col] += cc;
}
return arr;
}
Renderer.register('table', TableWidget);