Reputation: 547
I used a form and some JavaScript to take data from an uploaded CSV file and created an HTML table based on that data. In addition, I added an extra column for user input. My issues is that I cannot figure out a manageable way to take the user input at each input tag and replace the input tag with the text they entered.
This is the code behind the table. When I implement it, there will not be a finite number of rows though. Instead the amount of rows will be based on the data from the CSV file.
var table = document.createElement('table');
table.classList.add('table');
var thead = document.createElement('thead');
var headRow = document.createElement('tr');
var columnNames = ["Col1", "Col2", "Col3", "Col4"];
for (var i = 0; i < 4; i++) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(columnNames[i]));
headRow.appendChild(th);
}
thead.appendChild(headRow);
var tbody = document.createElement('tbody');
for (var i = 0; i < 10; i++) {
var tr = document.createElement('tr');
for (var j = 0; j < 4; j++) {
var td = document.createElement('td');
if (j == 3) {
td.classList.add("input");
var input = document.createElement('input');
input.type = "text";
td.appendChild(input);
tr.appendChild(td);
continue;
}
td.appendChild(document.createTextNode("x"));
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(thead);
table.appendChild(tbody);
document.body.appendChild(table);
td { width: 25vw; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
Upvotes: 1
Views: 26903
Reputation: 346
If you consider the user is done entering the text when they switch to another input, you can attach a blur listener to each input.
<input type="text" onblur="z(this)">
z = function(input){
var newEl = document.createElement('span');
newEl.innerHTML = input.value;
input.parentNode.replaceChild(newEl, input);
}
here is fiddle https://jsfiddle.net/nqmhpp88/
Upvotes: 0
Reputation: 48600
You can toggle the cells between input and text cells by doing the following.
function toggleInputCells(button) {
var cells = document.getElementsByClassName('input');
for (var i = 0; i < cells.length; i++) {
var cell = cells[i];
var input = cell.getElementsByTagName('input')[0];
if (input != null) {
var text = input.value;
cell.innerHTML = text;
} else {
var text = cell.innerHTML;
cell.innerHTML = '';
var input = document.createElement('input');
input.type = "text";
input.value = text;
cell.appendChild(input);
}
}
}
var rows = 10;
var cols = 4;
var table = document.createElement('table');
table.classList.add('table');
var thead = document.createElement('thead');
var headRow = document.createElement('tr');
var columnNames = ["Col1", "Col2", "Col3", "Col4"];
for (var i = 0; i < 4; i++) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(columnNames[i]));
headRow.appendChild(th);
}
thead.appendChild(headRow);
var tbody = document.createElement('tbody');
for (var i = 0; i < rows; i++) {
var tr = document.createElement('tr');
for (var j = 0; j < cols; j++) {
var td = document.createElement('td');
if (j == 3) {
td.classList.add("input");
var input = document.createElement('input');
input.type = "text";
input.value = 'Row #' + (i + 1); // Add a value?
td.appendChild(input);
tr.appendChild(td);
continue;
}
td.appendChild(document.createTextNode("x"));
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(thead);
table.appendChild(tbody);
document.body.appendChild(table);
td { width: 25vw; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
<input type="button" value="Toggle Input" onClick="toggleInputCells(this)" />
You could also listen to when the user clicks down on the cell and convert it to an input. After they leave focus, you can convert it back into a regular text cell.
function makeEditable(e) {
var cell = e.target;
if (cell.dataset.editing !== 'true') {
cell.dataset.editing = true;
var text = cell.innerHTML;
cell.innerHTML = '';
var input = document.createElement('input');
input.addEventListener('blur', makeNonEditable);
input.type = "text";
input.value = text;
cell.appendChild(input);
}
}
function makeNonEditable(e) {
var input = e.target;
var text = input.value;
var cell = input.parentElement;
if (cell.dataset.editing === 'true') {
cell.dataset.editing = false;
cell.innerHTML = text;
}
}
var rows = 10;
var cols = 4;
var table = document.createElement('table');
table.classList.add('table');
var thead = document.createElement('thead');
var headRow = document.createElement('tr');
var columnNames = ["Col1", "Col2", "Col3", "Col4"];
for (var i = 0; i < 4; i++) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(columnNames[i]));
headRow.appendChild(th);
}
thead.appendChild(headRow);
var tbody = document.createElement('tbody');
for (var i = 0; i < rows; i++) {
var tr = document.createElement('tr');
for (var j = 0; j < cols; j++) {
var td = document.createElement('td');
if (j == 3) {
td.addEventListener('mousedown', makeEditable); // Add mousedown listener.
td.innerHTML = 'Row #' + (i + 1); // Add a value?
tr.appendChild(td);
continue;
}
td.appendChild(document.createTextNode("x"));
tr.appendChild(td);
}
tbody.appendChild(tr);
}
table.appendChild(thead);
table.appendChild(tbody);
document.body.appendChild(table);
td { width: 25vw; }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet"/>
Upvotes: 2