How to get the key names from the JavaScript array? - javascript

I am creating a page where I want to print the values like below the code snippet using the map function in JavaScript.
var kvArray = [{a:1, b:2},{a:3, b:4},{a:5, b:6}];
function getValue(item,index) {
var vm="<table/>"
var fullValue =[item.a +" "+ item.b];
var v=vm+fullValue
return v;
}
function myFunction() {
document.getElementById("demo").innerHTML =kvArray.map(getValue).join(" ")
}
I am getting the output like this:
1 2
3 4
5 6
But I want the actual output like this:
a b
1 2
3 4
5 6

Please see the following snippet for a working example:
var kvArray = [{a:1, b:2},{a:3, b:4},{a:5, b:6}]
var asCell = v => `<td>${v}</td>`
var asRow = v => `<tr>${v}</tr>`
$('#demo > thead > tr').html(
Object.keys(kvArray[0]).map(key => asCell(key))
)
$('#demo > tbody').html(
kvArray.map(entry => {
return asRow(Object.keys(entry).map(k => {
return asCell(entry[k])
}).join())
})
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="demo">
<thead>
<tr></tr>
</thead>
<tbody></tbody>
</table>
I used Object.keys(kvArray[0]) to get the "column names".

var kvArray = [{a:1, b:2},{a:3, b:4},{a:5, b:6}];
function getValue(item,index)
{
var vm="<table/>"
var fullValue =[item.a +" "+ item.b];
var v=vm+fullValue
return v;
}
function createTable(kvArray)
{
var tableOpening="<table>";
var tableClosing="</table>";
var headerOpening= "<th>";
var headerClosing= "</th>";
var rowOpening= "<tr>";
var rowClosing= "</tr>";
var cellOpening= "<td>";
var cellClosing= "</td>";
// get the keys from the first element
var keys = Object.keys(kvArray && kvArray[0]) ;
// create a header
var header = rowOpening;
for (var keyIndex in keys) {
header += headerOpening + keys[keyIndex] + headerClosing + "\n";
}
header += rowClosing;
var table = tableOpening + header;
// create a row for each element
for (var itemIndex in kvArray) {
// open the row element
var rowLine = rowOpening;
for (var keyIndex in keys) {
// fill the cells
rowLine += cellOpening + kvArray[itemIndex][keys[keyIndex]] + cellClosing + "\n";
}
// close the row element
rowLine += rowClosing;
// add the current row to the table
table += rowLine;
}
// close the table
table += tableClosing;
return table;
}
Now just use this function for creating a table like so:
document.getElementById("demo").innerHTML = createTable(kvArray);
I know this is not as short as some of the answers given here, but it is much simpler to understand, as you obviously lack some concepts, namely your code was creating in each row and you were lucky it worked.

Related

How can I add a table column dynamically in JavaScript?

I have two arrays and need to write the data from both to two columns of a table. At this point I can write correctly data from the first array only and when I want to add the second array data, it gets added into rows.
orderGelen and userNameArr are my arrays. Here you can see my code:
for(let data of orderGelen){ 
dataHtmlIds += `<tr><td>${data}</td>`;
}
for(let usr of userNameArr){ 
dataHtmlUsr += `<td>${usr}</td></tr>`;
}
dataHtml = dataHtmlIds + dataHtmlUsr;
console.log(dataHtml);
And here I write that to table:
function tableConfig() { 
tableBody.innerHTML = dataHtml;
}
How can I make the second column userNameArr data?
Try to put two arrays in one array like this
const all = orderGelen.map((item, index) => ({ id: item, username: userNameArr[index] }));
let html = '<table>';
for (let row of all) {
html += `<tr><td>${row.id}</td><td>${row.username}</td></tr>`;
}
html+='</table>'
console.log(html);
you could do something like
var dataHtml = "";
for (
let i = 0, j = 0;
i < userNameArr.length || j < orderGelen.length;
i++, j++
) {
dataHtml += `<tr>`;
dataHtml += `<td>${userNameArr[i] ? userNameArr[i] : ""}</td>`;
dataHtml += `<td>${orderGelen[j] ? orderGelen[j] : ""}</td>`;
dataHtml += `</tr>`;
}
and you could write to the table like
function tableConfig() {
tableBody.innerHTML = dataHtml;
}
Hope this helps

Javascript object property returns as undefined only when called from inside another function

I created 3 objects that nest arrays of one another - we'll call them Table, Row and Column so I can show you what's wrong. Table has an array of Rows, and Row has an array of Columns. When I call properties of the Rows from Table, no problem. When I call properties of the Columns from Row, it says undefined, but in the debugger and the console it recognizes the object and it's properties. Maybe I've been staring at it too long but I can't see a fundamental difference.
I stripped the Table layer to be sure it wasn't an issue with nested objects. Here's the code, not working:
function Column()
{
this.sampleProp = "testprop";
this.content = "<td>sometext</td>";
}
function Row(columns)
{
this.columns = [];
this.columns = columns;
this.outputRows = function()
{
var temp = "<tr>";
for(var i = 0; i < this.columns.length; i++)
{
//this is the line that doesn't work and comes out as undefined:
temp += this.columns[i].content;
console.log("Problem: " + this.columns[i].content);
//yet the object exists, and has the correct properties:
console.log(this.columns[i]);
}
temp += "</tr>";
return temp;
};
}
function test()
{
var col = new Column();
console.log("Printing out the value from here works fine: " + col.content);
var cols = [col];
console.log("It's also fine when it's called from an array: " + cols[0].content);
var row = new Row([cols]);
console.log(row.outputRows());
}
Here is the interaction between the parent layer and the rows, working fine:
function Table(rows)
{
this.rows = [];
this.rows = rows;
this.outputTable = function()
{
var temp = "<table>";
for(var i = 0; i < this.rows.length; i++)
{
temp += this.rows[i].outputRows();
}
temp += "</table>";
return temp;
};
}
and the updated test function:
function test()
{
var column = new Column();
var cols = [column];
var row = new Row([cols]);
console.log(row.outputRows());
var rs = [row, row];
var table = new Table(rs);
console.log(table.outputTable());
}
Two rows print out as expected this way, with undefined inside each. I originally had column.content written as a function, it doesn't make a difference.
Please tell me what stupid mistake I'm missing here!
Change that line :
var row = new Row([cols])
into
var row = new Row(cols)
since cols is already an array, you don't need to put it in an array again.
function Column() {
this.sampleProp = "testprop";
this.content = "<td>sometext</td>";
}
function Row(columns) {
// removed this.columns = [] since you are assigning it in the next line
this.columns = columns;
this.outputRows = function() {
var temp = "<tr>";
for (var i = 0; i < this.columns.length; i++) {
//this is the line that doesn't work and comes out as undefined:
temp += this.columns[i].content;
}
temp += "</tr>";
return temp;
};
}
function test() {
var col = new Column()
console.log("Printing out the value from here works fine: " + col.content);
var cols = [col];
console.log("It's also fine when it's called from an array: " + cols[0].content);
var row = new Row(cols); // the problem was here
console.log(row.outputRows());
}
test()

Sorting dynamic table in jquery

Sorry but I'm completly new to js and jquery.
I got dynamic table which values are in localstorage. I can add new row, delete row, and edit cells. This is working.
I want to add a sorting this table by clicked colum. I found here code and try it. It just working when I write table and not use my javascript to add rows from localstorage. Table in two cases looks same in html code. I have no idead why sorting isnt working with dynamic table.
This is w/o my dynamic table from localstore, sorting as supposed to:
http://jsfiddle.net/eW8Kg/1/
This is with table from localstorage(not working in jsfiddle?) on my comupter this is working good, but table is not sorting! (I left this static values):
http://jsfiddle.net/XAu5G/
I think my problem can be in creation of table content:
var Html = "<tbody>";
for (var i = 1; i < localStorage.length; i++) {
var input = "<td><input style='border:hidden' class=\"fields\" name = " + localStorage.key(i) + " type='text' onchange='change(\"" + localStorage.key(i) + "\")' /></td>"
Html += "<tr class=\"field\">";
for (var j = 0; j < 4; ++j) {
Html += input;
}
var button = "<td><input type='button' value = 'Usuń' onclick='Remove(\"" + localStorage.key(i) + "\")'></td>";
Html += button + "</tr>";
}
Html += "<tr id=\"actions\"></tr></tbody>"
document.getElementById("list").innerHTML += Html;
This jquery code do sorting:
$(document).ready(function() {
var table = $('#list');
jQuery.fn.sortElements = (function() {
var sort = [].sort;
return function(comparator, getSortable) {
getSortable = getSortable || function() {return this;};
var placements = this.map(function() {
var sortElement = getSortable.call(this),
parentNode = sortElement.parentNode,
// Since the element itself will change position, we have
// to have some way of storing it's original position in
// the DOM. The easiest way is to have a 'flag' node:
nextSibling = parentNode.insertBefore(
document.createTextNode(''),
sortElement.nextSibling
);
return function() {
if (parentNode === this) {
throw new Error(
"You can't sort elements if any one is a descendant of another."
);
}
// Insert before flag:
parentNode.insertBefore(this, nextSibling);
// Remove flag:
parentNode.removeChild(nextSibling);
};
});
return sort.call(this, comparator).each(function(i) {
placements[i].call(getSortable.call(this));
});
};
})();
$('#x').click(function(){
$('#list').hide();
});
$('#nazwa-header').wrapInner('<span title="sort this column"/>').each(function() {
var th = $(this),
thIndex = th.index(),
inverse = false;
th.on('click', function() {
table.find('td').filter(function() {
return $(this).index() === thIndex;
}).sortElements(function(a, b) {
console.log($(a).find('input').val(),$(b).find('input').val());
return $(a).find('input').val() > $(b).find('input').val() ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}, function() {
// parentNode is the element we want to move
return this.parentNode;
});
inverse = !inverse;
});
});
});

Create HTML table from JavaScript object

I am a beginner of JavaScript and want to display an array of objects in HTML.
The format of the data is like this:
[
{"key":"apple","value":1.90},
{"key":"berry","value":1.7},
{"key":"banana","value":1.5},
{"key":"cherry","value":1.2}
]
I want to use a list with three columns (id, name, relevance) to display them. And the id can increase from 1 automatically.
Could anyone tell me how to write a javascript code to display it?
Please give me some materials or examples to learn.
Explanation
What you want is to fill a table (or another DOMElement) in HTML, with your JavaScript, which is executed dynamically once the page is loaded and your JSON object is received.
You want to loop through the object. The best way to do so would be with a for loop, and making sure our looping variable remains valid for the length of our object (all its attributes).
The best way to get the length of a JSON object is through myJSONObject.length: You select the keys of myJSONObject and return their count.
You can access the values stored in your JSON Object the following way, in your for loop (assuming the looping variable defined is named i): myJSONObject[i].theAttributeIWantToGet
Price formatting breakdown
Now, those prices need to have a proper format, don't they? So we'll check if any of the value attribute has less than 2 characters after the . within them. If they do, we add another decimal 0. We also add a $ before writing the formatted value. Here is a breakdown of how it works:
obj[i].value.toString().substring(startIndex, length)
We want to check the length after the . sign, so our startIndex will be the position of this dot within our string.
obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'),length)
We now need to set the length. We want to find the length of all what's after the dot, so we'll take the length of the whole string just to be safe.
Final result: obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2
This will return true or false. If it's true: There's less than 2 digits after the dot !
We add the if statement and the last zero:
if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2)
obj[i].value += "0";
Also: Why I use innerHTML instead of appendChild().
Solution
JSFiddle
HTML
<table>
<tbody id="tbody"></tbody>
</table>
JSON
[{
"key": "apple",
"value": 1.90
}, {
"key": "berry",
"value": 1.7
}, {
"key": "banana",
"value": 1.5
}, {
"key": "cherry",
"value": 1.2
}]
JavaScript
Note: The JSON object will be named obj in this instance.
var tbody = document.getElementById('tbody');
for (var i = 0; i < obj.length; i++) {
var tr = "<tr>";
/* Verification to add the last decimal 0 */
if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2)
obj[i].value += "0";
/* Must not forget the $ sign */
tr += "<td>" + obj[i].key + "</td>" + "<td>$" + obj[i].value.toString() + "</td></tr>";
/* We add the table row to the table body */
tbody.innerHTML += tr;
}
JSFiddle
It can be simply done by a small & smart process:
<table cellpadding="2" cellspacing="2" border="0" bgcolor="#dfdfdf" width="40%" align="center">
<thead>
<tr>
<th>Name</th>
<th width="20%">Age</th>
<th width="12%">Status</th>
</tr>
</thead>
<tbody id="tableData"></tbody>
</table>
<script type="text/javascript">
var mainObj = [
{
name: "Kapil",
age: 21,
status: "Active"
},
{
name: "John",
age: 28,
status: "Inactive"
},
{
name: "Deos",
age: 18,
status: "Active"
}
];
var k = '<tbody>'
for(i = 0;i < mainObj.length; i++){
k+= '<tr>';
k+= '<td>' + mainObj[i].name + '</td>';
k+= '<td>' + mainObj[i].age + '</td>';
k+= '<td>' + mainObj[i].status + '</td>';
k+= '</tr>';
}
k+='</tbody>';
document.getElementById('tableData').innerHTML = k;
</script>
You can do something like this:
var table = document.createElement("table");
//Add a header
var header = document.createElement("tr");
var idHeaderCell = document.createElement("th");
var nameHeaderCell = document.createElement("th");
var relevanceHeaderCell = document.createElement("th");
header.appendChild(idHeaderCell);
header.appendChild(nameHeaderCell);
header.appendChild(relevanceHeaderCell);
table.appendChild(header);
//Add the rest of the data to the table
for(var i = 0; i < data.length; i++) {
var id = (i + 1);
var name = data[i].key;
var relevance = data[i].value;
var tr = document.createElement("tr");
var idCell = document.createElement("td");
var nameCell = document.createElement("td");
var relevanceCell = document.createElement("td");
idCell.appendChild(document.createTextNode(id));
nameCell.appendChild(document.createTextNode(name));
relevanceCell.appendChild(document.createTextNode(relevance));
tr.appendChild(idCell);
tr.appendChild(nameCell);
tr.appendChild(relevanceCell);
table.appendChild(tr);
}
Here a function for build a table from any collection (array of objects)
Table creator
const data=[
{
name: "Kapil",
age: 21,
status: "Active"
},
{
name: "John",
age: 28,
status: "Inactive"
},
{
name: "Deos",
age: 18,
status: "Active",
testing: 'Gooo!!'
}
]
const createTable=function(data){
const table = document.createElement("table");
const header = document.createElement("tr");
const keys=Object.keys(data[0])
console.log(keys)
for(const key of keys){
const th=document.createElement("th");
th.appendChild(document.createTextNode(key));
header.appendChild(th);
}
table.appendChild(header);
const len=data.length
for(const row of data) {
const tr = document.createElement("tr");
for(const key of keys){
const td = document.createElement("td");
const content=row[key] ||''
td.appendChild(document.createTextNode(content));
tr.appendChild(td);
delete row[key]
}
/****
you can omit next cycle if all object have the same structor or if the first element of collection have all fields
****/
for(const key in row){
const th=document.createElement("th");
th.appendChild(document.createTextNode(key))
keys.push(key)
header.appendChild(th);
const td = document.createElement("td");
const content=row[key] ||''
td.appendChild(document.createTextNode(content));
tr.appendChild(td);
}
table.appendChild(tr);
}
return table
}
Array.map() combined with template literals comes in really handy for rendering HTML markup within Javascript for large objects in a scalable manner:
function tableMarkupFromObjectArray(obj) {
let headers = `
<th>Index</th>
${Object.keys(obj[0]).map((col) =>`
<th>${col}</th>`
).join('')}`
let content = obj.map((row, idx) => `
<tr>
<td>${idx}</td>
${Object.values(row).map((datum) => `
<td>${datum}</td>`
).join('')}
</tr>
`).join('')
let tablemarkup = `
<table>
${headers}
${content}
</table>
`
return tablemarkup
}
let myobj =[
{ "name": "apple", "rel": 1.90 },
{ "name": "berry", "rel": 1.7 },
{ "name": "banana", "rel": 1.5 },
{ "name": "cherry", "rel": 1.2 }
]
document.querySelector("#mydiv").innerHTML = tableMarkupFromObjectArray(myobj)
http://jsfiddle.net/4L7c5vad/
Here is my ES6 solution.
I have used the reduce operation to construct a Set storing the keys from all objects in the array:
function arrayToTable(data) {
const keys = [...data.reduce((all, obj)=>{
Object.keys(obj).forEach(key => all.add(key));
return all;
}, new Set())];
const header = keys.map(key => `<th>${key}</th>`).join('')
const tbody = data.map(row => keys.map(key => `<td>${row[key]}</td>`).join('')).map(row => `<tr>${row}</tr>`)
return `<table>
<thead><tr>${header}</tr></thead>
<tbody>${tbody}</body>
</table>`;
}
Iterate through the list and retrieve the data for each item this way (assuming your data is in a var called data):
for (var i = 0; i < data.length; i++) {
var id = i + 1;
var name = data[i].key;
var relevance = data[i].value;
}
Then, do something with the variables in each loop, print them out however you want.
I am not totally sure what you are asking for. The title of you post seems like you are looking for JSON.stringfy like mentioned in the previous answer but apparently you are not.
Are you trying to create and HTML list, ? Can you please try to explain your need again? I doubt what you are trying to do is complicated and I sure we can help you if you give a little more detail and purpose of what you are trying to do.
I am going to guess that you are trying to display HMTL by looping over you JSON object. Try this pure JavaScript example:
var fruits = JSON.parse('[{"key":"apple","value":1.90}, {"key":"berry","value":1.7}, {"key":"banana","value":1.5}, {"key":"cherry","value":1.2} ]');
var tbl = document.createElement('table');
var thead = document.createElement("thead");
var tbody = document.createElement("tbody")
var tr_head = document.createElement("tr");
var th_id = document.createElement("th");
var th_name = document.createElement("th");
var th_price = document.createElement("th");
th_id.textContent = "Id";
th_name.textContent = "Name";
th_price.textContent = "Price";
tr_head.appendChild(th_id);
tr_head.appendChild(th_name);
tr_head.appendChild(th_price);
thead.appendChild(tr_head);
for(var i = 0, j = fruits.length; i < j; i++) {
var tr_body = document.createElement("tr");
var td_id = document.createElement("td");
var td_name = document.createElement("td");
var td_value = document.createElement("td");
td_id.textContent = i;
td_name.textContent = fruits[i].key;
td_value.textContent = fruits[i].value;
tr_body.appendChild(td_id);
tr_body.appendChild(td_name);
tr_body.appendChild(td_value);
tbody.appendChild(tr_body);
}
tbl.appendChild(thead);
tbl.appendChild(tbody);
console.log(tbl);
Maybe like this:
function obj2htmltable(obj) {
var html = '<table>';
for (var key in obj) {
var value = obj[key].toString();
html += '<tr><td>' + key + '</td><td>' + value + '</tr>';
}
html += '</table>';
return html;
}
If case of nested structure (objects inside object) obj2htmltable() could call itself recursively:
function obj2htmltable(obj) {
var html = '<table>';
for (var key in obj) {
var item = obj[key];
var value = (typeof(item) === 'object') ? obj2htmltable(item) : item.toString();
html += '<tr><td>' + key + '</td><td>' + value + '</tr>';
}
html += '</table>';
return html;
}

Iterate through a table using JavaScript to get values of specific cells

How can I iterate through a table using JavaScript to get the values of cells 4 and 5?
This is what I have:
function constructString() {
var table=document.getElementById('wcList');
for(var i=0; i<table.rows.length;i++){
var row = getElem(RowId + i);
var str_wc = table.rows[i].cells[1].firstChild.value;
var str_act = table.rows[i].cells[5].firstChild.value;
var str_coh = table.rows[i].cells[6].firstChild.value;
var str_mconf = table.rows[i].cells[7].firstChild.value;
var string1 = str_wc + row + str_act + row + str_coh + row + str_mconf + row;
}
}
Use innerHTML.
Try this:
function constructString() {
var table=document.getElementById('wcList');
for(var i=0; i<table.rows.length;i++){
// FIX THIS
var row = 0;
var str_wc=(table.rows[i].cells[1].innerHTML);
var str_act=(table.rows[i].cells[5].innerHTML);
var str_coh=(table.rows[i].cells[6].innerHTML);
var str_mconf=(table.rows[i].cells[7].innerHTML);
var string1=str_wc +row+str_act+row+str_coh+row+str_mconf+row;
alert(string1);
}
}

Categories

Resources