Javascript cut table to insert a tag <div> - javascript

I want to cut table after tr to insert a div and re-open the table :
Before :
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>
After :
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
</table>
<div onClick="fuse(this)">It works</div>
<table>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>
And return to first state on click.
Any idea (no jQuery).

A simple whay to do it is to use combination of DOM manipulation methods like insertAdjacentHTML to create new table and appendChild to move rows into new table:
function cutAfter(row) {
var table = row.parentNode.parentNode;
if (row.nextElementSibling) {
table.insertAdjacentHTML('afterend', '<table><tbody></tbody></table>');
var newTable = table.nextElementSibling.tBodies[0];
while (row.nextElementSibling) {
newTable.appendChild(row.nextElementSibling);
}
}
}
table {
margin-bottom: 10px;
}
table td {
border: 1px #AAA solid;
}
<table>
<tr onClick="cutAfter(this);">
<td>bla</td><td> 123 </td><td>Yes </td>
</tr>
<tr onClick="cutAfter(this);">
<td>bli</td><td> 456 </td><td>no</td>
</tr>
<tr onClick="cutAfter(this);">
<td>blu</td><td> 789 </td><td>hum</td>
</tr>
</table>

Here's a simple example, made of an HTML file (the structure) and a Javascript file (the behavior). The script uses node manipulation, so as to preserve existing handlers (e.g. added by other scripts). It also attaches event handlers directly, using element.onxxx, to keep things simple, but you should replace that by your favorite event manager.
var makeSplittable = function(table, joinText) {
init();
function init() {
var tBodies = table.tBodies;
for (var ii = 0; ii < tBodies.length; ii++) {
var rows = tBodies[ii].rows;
for (var j = 0; j < rows.length; j++) {
rows[j].onclick = split; // Replace with your favorite event manager
}
}
}
function split(evt) {
var rowIndex = this.rowIndex;
var tbody = findParent(this, "tbody");
var numRows = tbody.rows.length;
if (rowIndex < numRows - 1) {
var rows = [];
for (var ii = rowIndex + 1; ii < numRows; ii++) {
rows.push(tbody.rows[ii]);
}
var existingTable = findParent(this, "table");
var newTable = createTable(rows);
var joiner = createJoiner();
existingTable.parentNode.insertBefore(newTable, existingTable.nextSibling);
existingTable.parentNode.insertBefore(joiner, existingTable.nextSibling);
}
}
function createTable(rows) {
var table = document.createElement("table");
var tbody = document.createElement("tbody");
for (var ii = 0; ii < rows.length; ii++) {
tbody.appendChild(rows[ii]);
}
table.appendChild(tbody);
return table;
}
function createJoiner() {
var div = document.createElement("div");
var content = document.createTextNode(joinText);
div.appendChild(content);
div.onclick = join; // same
return div;
}
function join(evt) {
var previousTable = this.previousSibling;
var nextTable = this.nextSibling;
var tbody = previousTable.tBodies[previousTable.tBodies.length - 1];
var rows = nextTable.rows;
while (rows.length) {
tbody.appendChild(rows[0]);
}
nextTable.parentNode.removeChild(nextTable);
this.parentNode.removeChild(this);
}
function findParent(element, type) {
if (!element || !type) {
return null;
}
if (element.nodeName.toLowerCase() == type.toLowerCase()) {
return element;
}
return findParent(element.parentNode, type);
}
};
makeSplittable(document.getElementById("target"), "Merge adjacent tables");
table,
div {
margin: 5px 0;
}
tr:hover td {
background-color: orange;
}
td {
background-color: yellow;
cursor: pointer;
padding: 10px;
}
div {
color: #0c0;
cursor: pointer;
}
<table id="target">
<tr>
<td>bla</td>
<td>123</td>
<td>Yes</td>
</tr>
<tr>
<td>bli</td>
<td>456</td>
<td>no</td>
</tr>
<tr>
<td>blu</td>
<td>789</td>
<td>hum</td>
</tr>
</table>

A possibility, assuming that a DIV should not be inserted after the last TR if there has not been a cut, but it would have been nice to see your effort. Also assuming no <thead> or <tfoot>.
function isTagName(element, tagName) {
return element.tagName.toUpperCase() === tagName.toUpperCase();
}
function getClosest(element, tagName) {
var closest = null;
while (element !== document && !isTagName(element, tagName)) {
element = element.parentNode;
}
if (element !== document && isTagName(element, tagName)) {
closest = element;
}
return closest;
}
function insertAfter(newNode, referenceNode) {
return referenceNode.parentNode
.insertBefore(newNode, referenceNode.nextSibling);
}
function moveAppend(list, dest, from) {
var index = list.length - 1,
last;
for (last = from || 0; index >= last; index -= 1) {
dest.appendChild(list[index]);
}
return dest;
}
document.body.addEventListener('click', function(e) {
var target = e.target,
tr = getClosest(target, 'tr'),
newDiv,
newTable,
newBody,
next,
parent;
if (tr) {
if (tr.rowIndex < tr.parentNode.rows.length - 1) {
newDiv = document.createElement('div');
newDiv.appendChild(document.createTextNode('It works!'));
insertAfter(newDiv, getClosest(tr, 'table'));
newTable = document.createElement('table');
newBody = document.createElement('tbody');
moveAppend(tr.parentNode.rows, newBody, tr.rowIndex + 1);
newTable.appendChild(newBody);
insertAfter(newTable, newDiv);
}
} else if (isTagName(target, 'div') &&
isTagName(target.previousElementSibling, 'table') &&
isTagName(target.nextElementSibling, 'table')) {
next = target.nextElementSibling;
moveAppend(next.tBodies[0].rows, target.previousElementSibling.tBodies[0]);
parent = target.parentNode;
parent.removeChild(next);
parent.removeChild(target);
}
}, false);
table,
td {
border-style: solid;
border-width: 1px;
}
div {
background-color: yellow;
}
<table>
<tr>
<td>bla</td>
<td>123</td>
<td>Yes</td>
</tr>
<tr>
<td>bli</td>
<td>456</td>
<td>no</td>
</tr>
<tr>
<td>blu</td>
<td>789</td>
<td>hum</td>
</tr>
</table>

Related

Unselect highlighted row

I have this table, and I can't seem to find out how to unselect marked field, if it's clicked again? So a double-click on id 2 would select->unselect.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
rowSelected.style.backgroundColor = "yellow";
rowSelected.className += " selected";
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I thought about making some kind of count on the rowID, so if it's clicked more than once after each other, then it would toggle between select/unselect?
You can solve it by doing something similar to this, this will first check the selected row for the selected class and remove it if it is found, otherwise, it'll add it to the row you clicked. After that is done, this function will loop through all other rows, check if they aren't the clicked row and remove the selected state accordingly.
So now once you click, your code will look for selected on the row you clicked, if it is found, it'll remove that class to reset the styling, if it isn't found, it'll add the selected class. After this, the code will check all rows to see if they're not the selected row and style them accordingly.
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function() {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row !== rowId) {
rowsNotSelected[row].style.backgroundColor = "";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if (rowSelected.classList.contains('selected')) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove('selected');
} else {
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
Hope this helps!
function highlight_row() {
var table = document.getElementById('testresultsTable');
var cells = table.getElementsByTagName('td');
for (var i = 0; i < cells.length; i++) {
// Take each cell
var cell = cells[i];
// do something on onclick event for cell
cell.onclick = function () {
// Get the row id where the cell exists
var rowId = this.parentNode.rowIndex;
var rowsNotSelected = table.getElementsByTagName('tr');
for (var row = 0; row < rowsNotSelected.length; row++) {
if(row!==rowId){
rowsNotSelected[row].style.backgroundColor = "white";
rowsNotSelected[row].classList.remove('selected');
}
}
var rowSelected = table.getElementsByTagName('tr')[rowId];
if(rowSelected.classList.contains("selected")) {
rowSelected.style.backgroundColor = "";
rowSelected.classList.remove("selected");
}
else{
rowSelected.style.backgroundColor = "yellow";
rowSelected.classList.add("selected");
}
}
}
} //end of function
window.onload = highlight_row;
<table id="testresultsTable">
<thead>
<th>ID</th>
<th>Tests</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>TESTRUN1</td>
</tr>
<tr>
<td>2</td>
<td>TESTRUN2</td>
</tr>
<tr>
<td>3</td>
<td>TESTRUN3</td>
</tr>
</tbody>
</table>
I'd do it like this
var selected;
(function () {
var rows = document.querySelectorAll('#testresultsTable > tbody > tr');
rows.forEach(tr => tr.addEventListener('click', () => {
if(selected === tr){
selected.classList.remove('selected');
selected = undefined;
}
else {
if(selected) selected.classList.remove('selected');
selected = tr;
tr.classList.add('selected');
}
}));
})();
tbody > tr {
cursor: pointer;
user-select: none;
}
tr.selected {
background-color: yellow;
}
<table id="testresultsTable">
<thead><th>ID</th><th>Tests</th></thead>
<tbody>
<tr><td>1</td><td>TESTRUN1</td></tr>
<tr><td>2</td><td>TESTRUN2</td></tr>
<tr><td>3</td><td>TESTRUN3</td></tr>
</tbody>
</table>

Append table array value to another array

I have this code below that popups the cell value whenever the user clicks a specific cell.
What I'm currently trying to do is when the user clicks a cell i want that cell value to be appended to another column. I tried using the push method but it doesn't seem to be working. I'm not sure if I'm doing it the wrong way
JFiddle
HTML:
<table id="fruitsTable" class="fruitstableroni skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
JavaScript:
var tbl = document.getElementById("fruitsTable");
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++)
tbl.rows[i].cells[j].onclick = function () {
obj[key2].push(this); //Trying to push it to the second column.
console.log(this);
};
}
}
function getval(cel) {
//console.log(cel.innerHTML);
}
var obj = {};
var key = "Red Fruits";
obj[key] = ['Apple', 'Cherry', 'Strawberry'];
var myArray = [];
myArray.push(obj);
var key2 = "Green Fruits";
obj[key2] = ['Watermelon', 'Durian', 'Avacado'];
var myArray2 = [];
myArray2.push(obj);
var key3 = "Random Fruits";
obj[key3] = ['Soursop', 'Papaya', 'Pineapple', 'Melon'];
var myArray3 = [];
myArray3.push(obj);
var $header = $("<tr>"),
cols = 0,
bodyString = "";
$.each(obj, function(key, values) {
cols = Math.max(cols, values.length); // find the longest
$header.append($('<th/>').text(key + ": " + values.length));
});
for (var i = 0; i < cols; i++) { // or use .map, but this is more undertandable for beginners
bodyString += '<tr>';
$.each(obj, function(key, values) {
bodyString += '<td>' +
(values[i] ? values[i] : "") + // ternary - instead of using if/else
'</td>';
});
bodyString += '</tr>';
}
$('.fruitsTableClass thead').html($header);
$('.fruitsTableClass tbody').html(bodyString);
var tbl = document.getElementById("fruitsTable");
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++)
tbl.rows[i].cells[j].onclick = function() {
getval(this);
obj[key2].push(this);
};
}
}
function getval(cel) {
alert(cel.innerHTML);
}
.class {
font-family: Open Sans;
}
.center {
display: flex;
justify-content: center
}
.skillsTable th {
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
}
table {
float: left;
border-collapse: collapse;
width: 70%
}
td {
border-left: 1px solid #AAA5A4;
border-right: 1px solid #AAA5A4;
padding-top: 8px;
padding-left: 11px;
font-size: 15px;
}
th {
color: #0080ff;
font-weight: normal;
border-bottom: 1px solid #AAA5A4;
padding-bottom: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<table id="fruitsTable" class="fruitsTableClass skillsTable class">
<thead></thead>
<tbody></tbody>
</table>
</div>
Restructure your code to have a method to redraw UI and to enable event listeners:
function redraw (obj) {
var $header = $('<tr>'),
cols = 0,
bodyString = ''
$.each(obj, function (key, values) {
cols = Math.max(cols, values.length) // find the longest
$header.append($('<th/>').text(key + ': ' + values.length))
})
for (var i = 0; i < cols; i++) { // or use .map, but this is more undertandable for beginners
bodyString += '<tr>'
$.each(obj, function (key, values) {
bodyString += '<td>' +
(values[i] ? values[i] : '') + // ternary - instead of using if/else
'</td>'
})
bodyString += '</tr>'
}
$('.fruitsTableClass thead').html($header)
$('.fruitsTableClass tbody').html(bodyString)
}
function listener (obj) {
tbl = document.getElementById('fruitsTable')
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++)
tbl.rows[i].cells[j].onclick = function () {
getval(this)
obj[key2].push(this.innerHTML)
redraw(obj)
listener(obj)
};
}
}
}
function getval (cel) {
alert(cel.innerHTML)
}
redraw(obj)
listener(obj)
JSFiddle - https://jsfiddle.net/gnm8wv5f/
To add rows or cells to a table, you should use the methods insertRow() and insertCell().
Example, if you want to add a cell at the beginning of a row (from w3schools):
var row = document.getElementById("myRow");
var x = row.insertCell(0);
x.innerHTML = "New cell";
Or, to insert at the end:
var x = row.insertCell(row.cells.length);
Using cells.length you can find the number of cells in a particluar row, in that way you could know where to insert the new cell.
More info in: w3 | MDN
Try this code.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var daraArray=[];
$(document).ready(function(){
$(".classTd").click(function(){
//console.log($(this).html());
daraArray.push($(this).html());
console.log(daraArray);
});
});
</script>
<style type="text/css">
.classTd{
text-align: center;
}
</style>
</head>
<table id="fruitsTable" class="fruitstableroni skillsTable class" border="1">
<thead></thead>
<tbody>
<tr>
<td class="classTd" width="10%">1</td>
<td class="classTd" width="10%">2</td>
<td class="classTd" width="10%">3</td>
</tr>
<tr>
<td class="classTd" width="10%">4</td>
<td class="classTd" width="10%">5</td>
<td class="classTd" width="10%">6</td>
</tr>
<tr>
<td class="classTd" width="10%">7</td>
<td class="classTd" width="10%">8</td>
<td class="classTd" width="10%">9</td>
</tr>
</tbody>
</table>
</html>
The other answers here are good but you should definitely try AngularJs. The ng-repeat tag will easily cater your functionality.

Adding table rows and column dynamically with jQuery

I'm trying to add rows and columns to a table using user input values to determine the number of rows and columns dynamically using jQuery. Below is my code which actually adds rows and columns but not according to the user's inputs
function makeGrid() {
let numOfRow = 0; let numOfCol = 0;
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
}
makeGrid();
Assuming a user inputs numOfRow = 2 and numOfCol = 2, I should have a table like this
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
Problem is my code seems to be adding extra but I haven't been able to figure it out. This is the result of my code
<tbody class="grid-canvas">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
How do I fix my code?
try changing your code from:
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
for (var i = 1; i <= numOfRow; i++) {
let row = $('.grid-canvas').append('<tr>');
for (col = 1; col <= numOfCol; col++) {
$('tr').append('<td></td>');
}
}
});
into this
$('#submit').on('click', function() {
numOfRow = $('#height').val();
numOfCol = $('#width').val();
var body = $('.grid-canvas');
for (var i = 1; i <= numOfRow; i++) {
let row = $('<tr></tr>');
for (col = 1; col <= numOfCol; col++) {
row.append('<td></td>');
}
body.append(row);
}
});
what i have done in the above code is created a separate object for the table's body and then once my rows are created with the columns, I append them back to the table object.
Pure javascript code is here
function f(x, y) {
var rows = x,
rowButtonNumber = y;
var table = document.getElementById("myTable");
table.innerHTML = "";
for (var i = 0; i < rows; i++) {
var tr = document.createElement("tr");
table.appendChild(tr);
for (var j = 0; j < rowButtonNumber; j++) {
var td = document.createElement("td");
var btn = document.createElement("button");
btn.innerHTML = "btn " + (i + 1);
btn.id = "btn-" + i;
btn.onclick = function() {
alert(this.innerHTML);
};
td.appendChild(btn);
tr.appendChild(td);
}
}
}
function go() {
var row = document.getElementById("row").value;
var col = document.getElementById("col").value;
f(row, col);
}
<html>
<head>
<style>
td {
width: 200px;
height: 200px;
}
button {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
Rows
<input id="row" type="number" placeholder="Rows" />
<br> Columns
<input id="col" type="number" placeholder="Columns" />
<button onclick="go()">Go</button>
<table id="myTable" cellspacing="50">
</table>
</body>
It does not seem you are using the row variable. I would suggest appending newly created td to row instead of $('tr').

`appendChild(htmlobject)` only append the last child form an array of data

I'm making a shopping cart and will load the products of inside the cart after a XMLHttpRequest. Because the complexity of the table rows I've extracted this inside my HTML code (in code below see: #sampleBody). This contains the default markup of the row.
When I've done the request, I take the sampleBody and will append them to the cartBody. This I'll do alter every loop in over data. The problem is that only the first element is visible (I'm looping backwards).
P.S.: In code below I've just add the code what happens after the request.
(function() {
'use strict';
var sampleBody, cartBody;
var data = [{
name: "product 1",
price: 15,
quantity: 2,
total: 30
}, {
name: "name of product 2",
price: 10,
quantity: 3,
total: 30
}]
function init() {
sampleBody = document.getElementById('sampleBody');
cartBody = document.getElementById('cartBody');
}
init();
var renderCart = function(data) {
var html = document.createDocumentFragment();
for (var i = data.length; i--;) {
sampleBody.querySelector('#name').innerText = data[i].name;
sampleBody.querySelector('#price').innerText = data[i].price;
sampleBody.querySelector('#quantity').value = data[i].quantity;
sampleBody.querySelector('#total').innerText = data[i].total;
html.appendChild(sampleBody);
}
while (cartBody.firstChild) {
cartBody.removeChild(cartBody.firstChild);
}
cartBody.appendChild(html);
};
renderCart(data);
})();
.hidden {
display: none;
}
table {
width: 100%;
}
td, th {
border: solid 1px black;
padding: 5px;
}
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
</tr>
</thead>
<tbody id="cartBody">
<tr>
<td colspan="4">Loading...</td>
</tr>
</tbody>
</table>
<table class="hidden">
<tr id="sampleBody">
<td id="name"></td>
<td>€<span id="price"></span></td>
<td>
<button>+</button>
<input type="text" id="quantity">
<button>-</button>
</td>
<td>€<span id="total"></span></td>
</tr>
<table>
You have to clone your sampleBody node in your foor loop statement:
for (var i = data.length; i--;) {
var node = sampleBody.cloneNode(true);
node.setAttribute('id', node.getAttribute('id')+i);
node.querySelectorAll('*[id]').forEach(elt =>
elt.setAttribute('id', elt.getAttribute('id')+i)
);
node.querySelector('#name'+i).innerText = data[i].name;
node.querySelector('#price'+i).innerText = data[i].price;
node.querySelector('#quantity'+i).value = data[i].quantity;
node.querySelector('#total'+i).innerText = data[i].total;
html.appendChild(node);
}
We can also remove the ids and replace them by a name attribute:
HTML:
<table class="hidden">
<tr name="sampleBody">
<td name="name"></td>
<td>€<span name="price"></span></td>
<td>
<button>+</button>
<input type="text" name="quantity">
<button>-</button>
</td>
<td>€<span name="total"></span></td>
</tr>
<table>
JS:
...
function init() {
sampleBody = document.querySelector('table.hidden > tr[name="sampleBody"]');
cartBody = document.getElementById('cartBody');
}
...
for (var i = data.length; i--;) {
var node = sampleBody.cloneNode(true);
node.querySelector('*[name="name"]').innerText = data[i].name;
node.querySelector('*[name="price"]').innerText = data[i].price;
node.querySelector('*[name="quantity"]').value = data[i].quantity;
node.querySelector('*[name="total"]').innerText = data[i].total;
html.appendChild(node);
}
The issue is that id attribute values should be unique in valid HTML. So you should not use id for what you are doing. You can use class for this instead, and then filter for the one you want to assign the text to, like this:
for (var i = data.length; i--;) {
sampleBody.querySelectorAll('.name')[i].innerText = data[i].name;
sampleBody.querySelectorAll('.price')[i].innerText = data[i].price;
sampleBody.querySelectorAll('.quantity')[i].value = data[i].quantity;
sampleBody.querySelectorAll('.total')[i].innerText = data[i].total;
html.appendChild(sampleBody);
}
It would in fact be more efficient to perform those 4 querySelectorAll once, before the loop:
var names = sampleBody.querySelectorAll('.name');
var prices = sampleBody.querySelectorAll('.price');
var quantities = sampleBody.querySelectorAll('.quantity');
var totals = sampleBody.querySelectorAll('.total');
for (var i = data.length; i--;) {
names[i].innerText = data[i].name;
prices[i].innerText = data[i].price;
quantities[i].value = data[i].quantity;
totals[i].innerText = data[i].total;
html.appendChild(sampleBody);
}

Create a table from an object jquery/javascript

I am trying to implement the following.
A user enters a sentence into a textbox following which a table is created. An example would be this.
Input: "This is what I want to achieve"
Result:
Currently, based on the code I have there is an object that looks like this:
{t: ["this", "to"], i: ["is", "i"], w: ["what", "want"], a: ["achieve"]};
Below is the current code I have (also see jsfiddle here).
I am able to take the input string and create a table with a row which has the first letter of each word.
HTML
<textarea id="text-input" name="textarea" rows="5" cols="25">This is what I want to achieve</textarea>
<button class="calculate">Calculate</button>
<table>
<tbody>
<tr class="words-header"></tr>
</tbody>
</table>
Javascript
$(document).ready(function() {
$(".calculate").click(function() {
var result = {},
arr = [];
var array = $("#text-input").val().toLowerCase().split(" ");
for (var i = 0; i < array.length; i++) {
if (typeof result[array[i][0]] == 'undefined') {
result[array[i][0]] = [];
}
result[array[i][0]].push(arr[i]);
}
for (var key in result) {
$(".words-header").append("<td>" + key.toUpperCase() + "</td>");
}
});
});
I believe the final table should look like this if it helps:
<table>
<tr>
<td>A</td>
<td>I</td>
<td>T</td>
<td>W</td>
</tr>
<tr>
<td>achieve</td>
<td>is</td>
<td>this</td>
<td>what</td>
</tr>
<tr>
<td> </td>
<td>i</td>
<td>to</td>
<td>want</td>
</tr>
</table>
You can do it this way (Try it by clicking the Run code snippet button below):
var app = app || {};
(function() {
"use strict";
var result, arr;
app.initialize = {
init: function() {
app.splitWords.init();
}
};
app.splitWords = {
init: function() {
$(".calculate").click(function() {
result = [];
arr = $("#text-input").val().split(" ");
app.createMultiArray.init(arr);
});
}
};
app.createMultiArray = {
init: function(array) {
for (var i = 0; i < array.length; i++) {
var letter = array[i][0].toLowerCase();
if (typeof result[letter] == 'undefined') {
result[letter] = [];
}
result[letter].push(array[i]);
}
// I added this method
app.buildTable.init(result);
}
};
app.buildTable = {
init: function(result) {
var headers = Object.keys(result),
max_rows = 0,
rows_html = '';
headers.sort();
app.createHeaders.init(headers);
// Determine how many rows you'll need
for (var i = 0; i < headers.length; i++) {
if(result[headers[i]].length > max_rows) { max_rows = result[headers[i]].length; }
}
// Loop "max_rows" times
for (var i = 0; i < max_rows; i++) {
rows_html += '<tr>';
// Loop through all letters
for(var j = 0; j < headers.length; j++) {
rows_html += '<td>';
if(i < result[headers[j]].length) {
rows_html += result[headers[j]][i];
}
rows_html += '</td>';
}
rows_html += '</tr>';
}
$(".words-header").after(rows_html);
}
};
app.createHeaders = {
init: function(headers) {
// Empty the table in case of multiple tries
$(".words-header").parent().html('<tr class="words-header"></tr>');
for (var i = 0; i < headers.length; i++) {
$(".words-header").append("<td>" + headers[i].toUpperCase() + "</td>");
}
}
};
app.docOnReady = {
init: function() {
app.initialize.init();
}
};
$(document).ready(app.docOnReady.init);
})(jQuery);
#results-table table{ border-collapse: collapse; } #results-table td{ border: 1px solid #000; padding: .2em;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<textarea id="text-input" name="textarea" rows="5" cols="25">This is what I want to achieve</textarea>
<button class="calculate">Calculate</button>
<div id="results-table">
<table>
<tbody>
<tr class="words-header"></tr>
</tbody>
</table>
</div>

Categories