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.