/***********
** Creates a given element and appends them.
* @param {String} tag tagName of element to be
* created
* @param {DOM Object} parent DOM object to append to
* @param {Number} times number of times tag is
* created
* @param {String} content string in
* each cell (Default is empty)
* @returns {DOM Object|Array} DOM object or an array of DOM
* objects
*/
const setDOM = (tag, parent, times, content = '') => {
let nodeList = [];
for (let i = 0; i < times; i++) {
let node = document.createElement(tag);
parent.appendChild(node);
node.insertAdjacentHTML('beforeEnd', content);
nodeList.push(node);
}
return times > 1 ? nodeList : times === 1 ? nodeList.pop() : null;
}
/** Event handler passes an Event Object (e) **/
const buildTable = e => {
/** Event Properties/Methods
-Stop normal behavior of form submits
-(io) is all form controls (fieldset, legend, input,
button)
*/
e.preventDefault();
const io = e.currentTarget.elements;
/** Form Data
-(r) number of rows
-(c) number of columns
-(cnt) text if any from #edit
*/
let r = parseInt(io.rows.value);
let c = parseInt(io.cols.value);
let cnt = io.edit.innerHTML;
/** Create the Table
-Clear #box
-Create <table> in #box
-Create <tbody> in table
*/
io.box.replaceChildren();
const table = setDOM('table', io.box, 1);
const tB = setDOM('tbody', table, 1);
/** Create Rows & Columns
-Create all <tr>
-if an array is returned...
...Use .forEach() to create the <td> for each <tr>...
...Otherwise just run setDOM() once to create the <td>
*/
const allRows = setDOM('tr', tB, r);
if (Array.isArray(allRows)) {
allRows.forEach((row, idx) => setDOM('td', allRows[idx], c, cnt));
} else {
setDOM('td', allRows, c, cnt);
}
/** Create tHead
-if #head is checked...
...Create <thead>...
...Create <tr>...
...Create all <th>
*/
if (io.head.checked) {
let tH = table.createTHead();
let hRow = setDOM('tr', tH, 1);
setDOM('th', hRow, c, cnt);
}
/** Create tFoot
-if #foot is checked...
...Create <tfoot>...
...Create <tr>...
...Create all <td>
*/
if (io.foot.checked) {
let tF = table.createTFoot();
let fRow = setDOM('tr', tF, 1);
setDOM('td', fRow, c, cnt);
}
};
// Reference the form and listen for the submit event
const UI = document.forms[0];
UI.onsubmit = buildTable;
*, *::before {box-sizing: border-box;}:root {font: 1ch/1.25 'Segoe UI';}body {font-size: 4ch;}.box {width: 100%;max-width: max-content;background: lightgrey;}.box:empty {border: 0;background: transparent;}.edit {width: 100%;min-width: 50vw;min-height: 50px;overflow-wrap: break-word;word-break: break-word;border: 0;outline: 0;padding: 0;}.group {display: flex;flex-flow: row wrap;justify-content: flex-start;align-items: center;}fieldset, button, input {border-radius: 4px;}input {display: inline-block;font-size: 100%;font-family: Consolas;}label {display: flex;align-items: center;margin-right: 2rem;margin-top: 4px;font-size: 100%;}label b {font-weight: 400;}button {display: block;float: right;width: 80px;margin: 4px 0;font-size: 100%;cursor: pointer;}.num {width: 5ch;}.chx {width: 15px;height: 15px;margin-bottom: -1px;cursor: pointer;}table {table-layout: fixed;border-collapse: collapse;width: 100%;}table, td, th {border: 1px solid #000;}th {background: lime;}tbody td {background: cyan;}tfoot td {background: tomato;}
<main>
<form id='UI'>
<fieldset>
<fieldset class='group'>
<legend>Rows & Columns</legend>
<label>Rows:......<sup>(max. 99)</sup>
<input id='rows' class='num' type='number' min='1' max='99' maxlegnth='3' required></label>
<label>Columns:.<sup>(max. 20)</sup>
<input id='cols' class='num' type='number' min='1' max='20' maxlegnth='3' required></label>
</fieldset>
<fieldset>
<legend>Optional text </legend>
<fieldset id='edit' class='edit' contenteditable></fieldset>
</fieldset>
<fieldset class='group'>
<legend>Optional Sections</legend>
<label><b>Table Head:</b> <input id='head' class='chx' type='checkbox'></label>
<label><b>Table Foot:</b> <input id='foot' class='chx' type='checkbox'></label>
</fieldset>
<button>GO</button>
<fieldset id='box' class='box'></fieldset>
</fieldset>
</form>
</main>