I have a challenge that make a table depending on what's on the inputs.
function createTable(){
let table = document.getElementById('table')
let row = document.getElementById('input-row').value
let column = document.getElementById('input-column').value
for(let rowIndex = 0; rowIndex < row; rowIndex ){
let tr = document.createElement('tr')
for(let colIndex = 0; colIndex < column; colIndex ){
let td = document.createElement('td')
tr.appendChild(td)
}
table.appendChild(tr)
document.getElementById('input-row').value = " "
document.getElementById('input-column').value = " "
if(row == " ") {
alert('Number of rows cannot be empty')
return false
}
if(row > 9) {
alert('Number of rows cannot be greater than 9')
return false
}
if(row <= 0) {
alert('Number of rows cannot be less than 1')
return false
}
}
}
<div >
<div >
<input type="number" max=9 min=0 id="input-row" maxlength="1">
<h3>Rows</h3>
</div>
<div >
<input type="number" max=9 min=0 id="input-column">
<h3>Columns</h3>
</div>
</div>
<div >
<button id="btn" onclick="createTable()">Create Table</button>
</div>
<div >
<table border="1" id="table">
</table>
</div>
for the validation only the if(row > 9) is working the other ones not.
Also, I want to erase the table when again I press the button, I don't know how to do it.
CodePudding user response:
I noticed some issues:
- Since you get the
row
value as astring
, you should use theString.length
property to check if it is empty. Or you can evaluate that no value is entered by comparing with""
. - You need to convert
row
to integer before comparing;parseInt()
method can be used for this purpose. - You should evaluate conditions before looping.
let table = document.getElementById('table');
let rowElement = document.getElementById('input-row');
let columnElement = document.getElementById('input-column');
function isValid() {
let row = rowElement.value;
if(row.length == 0){
alert('Number of rows cannot be empty');
return false;
}
if(parseInt(row) > 9) {
alert('Number of rows cannot be greater than 9');
return false;
}
if(parseInt(row) <= 0) {
alert('Number of rows cannot be less than 1');
return false;
}
return true;
}
function createTable(){
let row = rowElement.value;
let column = columnElement.value;
if(isValid(row))
{
for(let rowIndex = 0; rowIndex < row; rowIndex )
{
let tr = document.createElement('tr')
for(let colIndex = 0; colIndex < column; colIndex ){
let td = document.createElement('td')
tr.appendChild(td)
}
table.appendChild(tr);
document.getElementById('input-row').value = "";
document.getElementById('input-column').value = "";
}
}
}
<div >
<div >
<input type="number" max=9 min=0 id="input-row" maxlength="1">
<h3>Rows</h3>
</div>
<div >
<input type="number" max=9 min=0 id="input-column">
<h3>Columns</h3>
</div>
</div>
<div >
<button id="btn" onclick="createTable()">Create Table</button>
</div>
<div >
<table border="1" id="table"></table>
</div>
CodePudding user response:
If you have anything that requires user interaction, you'll need to listen for events (unless you are using prompt()
but that's just plain awful). The "click" event is the goto event but there are far better ones you could use especially if you use a <form>
. One event in particular is exclusively for the form:
submit
: When user is focused in a field and hits Enter/Return key or a<button>
,<input type="submit">
, or<input type="image">
is clicked the form will:validate itself if there is any
[required]
,[pattern]
,[min]
,[max]
, etc. attributes or any validation methods hooked in,gather all values from any fields with a
[name]
attribute,then send it to a server, and will return a response.
If it doesn't have a server to send it to, it will return a blank page. The example below will do everything when a "submit" event is fired, but it will not send data to a server. You should read the following:
Details are commented in the example below
/***********
** 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>