I try to build js
dynamically table generator with content editable cells. It works when table cells (td
) are empty since new table structure replace the old one.
My problem starts when user type on table and then want to make structure change (i.e. more/less
cells etc).
const theTable = document.querySelectorAll('.adTable')[0]; /* table el */
let codeToSave = []; /* this eventually send to server */
let tableContent = ''; /* dynamically table content */
adTableGenerator();
/* Change Event triggers generator */
const wizardInputs = document.querySelectorAll('form input[type="number"]');
for (var i=0; i < wizardInputs.length; i++) {
wizardInputs[i].addEventListener('change', adTableGenerator);
}
function adTableGenerator() {
const tableRows = Number(document.querySelector('#rowNum').value); /* get current rows number */
const tableCells = Number(document.querySelector('#cellsNum').value); /* get current cells number */
let contentCheck = theTable.querySelectorAll('td'); /* check if table is empty by it's TD elements */
// console.log(contentCheck.length);
if (contentCheck.length > 0) { /* if table NOT empty: */
for (var i=0; i < contentCheck.length; i++) { /* loop over TD's */
console.log('innerHTML: '+contentCheck[i].innerHTML); /* this sometime return <br> (if you type inside cells?) but not text */
/* this ALWAYS return <empty string> */
console.log('textContent: '+contentCheck[i].textContent);
/* try this because https://stackoverflow.com/questions/3593626/get-the-text-content-from-a-contenteditable-div-through-javascript
but it still ALWAYS returns <empty string> */
console.log('innerText: '+contentCheck[i].innerText);
if ( (contentCheck[i].textContent && contentCheck[i].textContent.trim() ) || (contentCheck[i].innerText && contentCheck[i].innerText.trim() ) !== '') {
alert('Table: YES Content YES');
tableContent = 'need to be done';
//theTable.innerHTML = tableContent;
}
else {
alert('Table: YES Content NO');
/* Fill table structure */
tableContent =
'<thead><tr>' +
new Array(tableCells).fill('<th contenteditable="true" oninput="saveState()">Title</th>').join('') +
'</tr></thead><tbody>' +
new Array(tableRows).fill('<tr>' +
new Array(tableCells).fill('<td contenteditable="true" oninput="saveState()"></td>').join('') +
'</tr>').join('')+
'</tbody>'
;
theTable.innerHTML = tableContent;
return;
};
};
}
else {
alert('Table: No');
tableContent =
'<thead><tr>' +
new Array(tableCells).fill('<th contenteditable="true" oninput="saveState()">Title</th>').join('') +
'</tr></thead><tbody>' +
new Array(tableRows).fill('<tr>' +
new Array(tableCells).fill('<td contenteditable="true" oninput="saveState()"></td>').join('') +
'</tr>').join('')+
'</tbody>'
;
theTable.innerHTML = tableContent;
};
};
/* Save table changes on array - this will be "undo" later on */
function saveState() {
codeToSave.push( theTable.parentElement.innerHTML );
//console.log(codeToSave);
};
/* Reset table */
const resetBtn = document.querySelectorAll('button[type="reset"]')[0];
resetBtn.addEventListener('click', function(){
document.querySelectorAll('.adTable')[0].innerHTML = '';
codeToSave.length = 0;
adTableGenerator();
});
/* demo css*/
label {display: block;}
form {width: 270px; float: left;}
div > form + div {width: calc(100% - 280px); min-width: 300px; float: right; overflow-x: auto;}
table {width: 100%; border-collapse: collapse;}
td, th {border: 1px solid black; height: 2em;}
<div>
<form>
<fieldset>
<label for="cellsNum">
<span>Cells</span>
<input type="number" min="2" value="8" id="cellsNum" />
</label>
<label for="rowNum">
<span>Rows</span>
<input type="number" min="2" value="8" id="rowNum" />
</label>
</fieldset>
<button type="reset">reset table</button>
</form>
<div>
<table class="adTable"></table>
</div>
</div>
Try to type on cells and then change rows/cells
number and you get this.
Please advice.