jQuery: JSON object children handling - javascript

I'm trying to make a <table> through a javascript function.
I'm getting a JSON element that looks like that :
header
["Nom", "Région", "Activité", 10 more...]
0 "Nom"
1 "Région"
2 "Activité"
// other fields
body
Object { entity0=[13], entity1=[13], entity2=[13], more...}
entity0
["Org2", "Org2", "Org2", 10 more...]
0 "Org2"
1 "Org2"
2 "Org2"
//Other fields
entity1
["gfhu", "rtyud", "dgud", 10 more...]
//Other entities
And I'm trying to decode it like that (I parse the JSON and give it to that function) :
function createTableEntity(tab, id){
table = '<table cellpadding="0" cellspacing="0" border="0" class="display" id="'+id+'">';
table = table + '<thead><tr>';
$(tab.header).children().each(function(){
table = table + '<td>' + this + '</td>';
});
table = table + '</tr></thead>';
table = table + '<tbody>';
$(tab.body).children().each(function(){
table = table + '<tr>';
$(this).children().each(function(){
table = table + '<td>' + $(this) + '</td>';
});
table = table + '</tr>';
});
table = table + '</tbody>';
table = table + '</table>';
//alert(table);
return table;
}
From the results I have, there are no children ($(tab.header).children().each(function(){});).
Where does it come from? How do I loop through the elements parsed from JSON?

You don't need jquery to loop through the result of a JSON parsing as it's a Javascript object.
If you have an array in tab.header, you simply can loop on it with
$.each(tab.header, function() {
Or more classicaly, without jquery, using
for (var i=0; i<tab.header.length; i++) {

Related

How to improve replaceWith performance on IE11

I am rendering an array of data in table element, the data can be filtered so the table should be updated with the new data.
I am using JQuery replaceWith() for replacing the old tbody element with new tbody which represents the new data, but it seems to take very long time on IE11 to be rendered when the length of the array of data is 1700.
This is my code:
var markup='', table = [] // 2D array of data;
markup += '<tbody>';
for (var row = 0; row < table.length; row++) {
markup += '<tr role="row">';
for (var col = 0; col < table[0].length; col++) {
markup += '<td>' + table[row][col] + '</td>';
}
markup += '</tr>';
}
markup += '</tbody>';
.$('#data-results > tbody').replaceWith(markup);
In my understanding, adding large strings of tags using .append() or .html() is supposed to be more efficient than adding through .replaceWith().
So, try my below lines of code to achieve the same you asked.
$('#data-results > tbody').empty();
$('#data-results > tbody').html(markup);
In otherway, you can also try .innerHTML
$('#data-results > tbody').empty();
$('#data-results > tbody').innerHTML = markup;

Sorting html table columns client side without third party other than jquery

I fetch data via a jQuery ajax call to a web api service. I do not want to be sending up request to have the server side do the Order By asc / desc per column so what I want to do is CLIENT SIDE HTML Table sorting
I have been using jQuery and Javascript throughout the project, but I would really prefer to NOT use 3rd party tools like jqgrid or datatable.net
What are my options?
I have the data in Javascript before it is getting spit out into html table rows so seems like an option to have a click event which sorts the data in the .each loop
Javascript/jQuery
function writeResponses(allData) {
var strResult = "<table id='headerTable' class='table'><thead id='headers'><th>ID</th><th>Location</th><th>Comment</th><th>Additional Information</th><th>Date Reported</th><th>TC Key</th>";
strResult += "<th>Loc Acct Num</th><th>TC Date</th><th>WorkedID</th><th>TC Type</th><th>Corrected TC Type</th></thead>";
$.each(allData, function (index, issues) {
strResult += "<tr><td>" + issues.DOCCCOIssuesId + "</td><td> " + issues.Location + "</td><td>" + issues.Comment + "</td>";
strResult += "<td>" + issues.AdditionalInformation + "</td><td>" + issues.DateReported + "</td><td>" + issues.TCKey + "</td>";
strResult += "<td>" + issues.LocAcctNum + "</td><td>" + issues.TCDate + "</td><td>" + issues.WorkedByNTID + "</td>";
strResult += "<td>"+issues.TCType+"</td><td>"+issues.CorrectedTCType+"</td></tr>";
});
strResult += "</table>";
$("#divResult").html(strResult);
}
html table generated
<table id="headerTable" class="table">
<thead id="headers">
<tr>
<th>ID</th><th>Location</th><th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>CCO</td>
<td>Compliment</td>
</tr>
<tr>
<td>2</td>
<td>afafd</td>
<td>oafaf</td>
</tr>
</tbody>
You can do your initial sort on the data as you receive it. allData appears to be an array so you can do:
allData.sort(function(a, b){
if(a.DOCCCOIssuesId < b.DOCCCOIssuesId ) return -1;
if(a.DOCCCOIssuesId > b.DOCCCOIssuesId ) return 1;
// other sort keys?
return 0;
});
If you want to have clickable sort columns the example below may help:
jQuery("table.stats").each(function() {
var $ = jQuery;
var tbl = $(this);
$('th', this).click(function() {
var clickRow = $(this).closest('tr');
var body = $(this).closest('tbody').get(0);
var col = $(this).index();
var sortKeys = $(body).find('tr').not(clickRow).map(function(idx, row) {
return {
row: row,
key: $('td', row).eq(col).text() // you can do all sorts of things besides simple text values. cache the key for efficiency
};
}).get();
sortKeys.sort(function(a, b) {
return a.key > b.key ? 1 : a.key < b.key ? -1 : 0;
});
for (var i = sortKeys.length - 1; i >= 0; i--) {
body.appendChild(sortKeys[i].row);
}
});
});

From a dynamic table, save separate tables from the master table

Say I have a dynamic table, something like this (just an example):
var table = '<table>';
for (var i=0; i<6; i++) {
table += '<tr>';
table += '<th>';
table += 'HEADER ' + i + '</th></tr>'
table += '<tr><td>one</td>';
table += '<td>two</td>';
table += '<td>three</td>';
table += '<td>four</td>';
table += '<td>five</td>';
table += '<td>six</td>';
table += '<td>seven</td>';
table += '<td>eight</td>';
table += '</tr>';
}
table += '</table>';
What I'd like to do is to take each header and its table data under the header and save each as a separate table. For example, the first table would be:
HEADER 0
1 2 3 4 5 6 7 8
The second table would be:
HEADER 1
1 2 3 4 5 6 7 8
etc...
NOTE: There's no guarantee that there's only one row under each header. Some may have multiple rows.
To get the first table I could do:
var indexval = $(table).find('tr:contains("1")').index();
var firstTable = $(table).find('tr:lt('+indexval+')');
$('#testarea').html(firstTable);
I'm aware I'm calling these "tables" and that may not be correct. But how to start at the "next" header and go the the one after that and save 'that' table? In the end I'd have a number of little tables I could print to the screen by calling their variable names.
Demo:
var table = '<table>';
for (var i = 0; i < 6; i++) {
table += '<tr>';
table += '<th>';
table += '<td>HEADER ' + i + '</td></th></tr>'
table += '<tr><td>one</td>';
table += '<td>two</td>';
table += '<td>three</td>';
table += '<td>four</td>';
table += '<td>five</td>';
table += '<td>six</td>';
table += '<td>seven</td>';
table += '<td>eight</td>';
table += '</tr>';
}
table += '</table>';
//$('#testarea').html(table);
var indexval = $(table).find('tr:contains("1")').index();
var firstTable = $(table).find('tr:lt(' + indexval + ')');
$('#testarea').html(firstTable);
td, th {
min-width: 50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='testarea'></div>
EDIT: I ended up solving my own problem by just using a couple of arrays to store each section of the table (each header and its immediate relevant rows under it). The first for loop gets the index value of the header, and the second for loop selects out the table rows (header and associated cells under it). The "firstRow" variable selects just the first header and its rows, the 'lastRow' variable does the same with the last header and row(s). Apologies for not initially putting the question in clear terms. The question was just asking how to segment out a large table into pieces with each header and its relevant rows underneath and save them as separate variables. My thinking was this would clean up my pagination method I've currently got on my site. When a 'page up' or 'page down' is clicked, it just loads the appropriate variable in the div on the page.
var firstRow = "";
var test = [];
var indexVal = [];
for (var i=2; i<7; i++) {
indexVal[i] = $(table).find('tr:contains('+('MC' + ' ' + i)+')').index();
}
firstRow = $(table).find('tr:lt('+indexVal[2]+')');
lastRow = $(table).find('tr:gt('+((indexVal[6]) - 1)+')');
for (var j=1; j<7; j++) {
test[j] = $(table).find('tr:lt('+indexVal[j + 1]+'):gt('+((indexVal[j]) - 1)+')');
}
The only issue I had was not being able to integrate the first and last rows into the for loops. I had to make them separate hand coded variables. But it works.
JSFIDDLE

Adding a row to JSON

I want to add a new row to my JSON when the user clicks a link. Here's my javascript: It's not erroring, but I am not getting updated JSON in my alert.
$(document).ready( function(){
people = {
"COLUMNS":["NAME","AGE"],
"DATA":[
["Jon","16"],
["Jerry","23"]
]
}
members = people.DATA;
var nc = "<table border=1 width=500><tr><td>name</td><td>age</td><td></td></tr>";
for(var i=0;i<members.length;i++)
{
nc+= '<tr><td>' + members[i][0] + '</td>';
nc+= '<td>' + members[i][1] + '</td>';
nc+= '<td>add a new person</td></tr>';
}
nc += "</table>";
$("#result").html(nc);
$(".addlink").click( function(){
// add another row to our JSON
people.DATA['NAME'] = "new";
people.DATA['AGE'] = "99";
alert(people.DATA);
return false;
});
});
That's not JSON, it's a Javascript object.
To add another item in the array, you create an array and add to it, as it is an array of arrays:
people.DATA.push(["new", "99"]);

Find the value of html table cell by passing column name for a particular row

I am dynamically creating a table using JSON so i dont know in advance how many column and/or rows will be generated.
I add a clicked event for the row that get selected.
Now my every table will have a column name ID
I want to find the value of ID for the selected row.
How can i achieve this?
I have googled a find a lot of sample which select the cell be index but not by column name.
My table is something like:
My table is generated like:
function CreateTableView(objArray, theme, enableHeader) {
// set optional theme parameter
if (theme === undefined) {
theme = 'mediumTable'; //default theme
}
if (enableHeader === undefined) {
enableHeader = true; //default enable headers
}
// If the returned data is an object do nothing, else try to parse
var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
var str = '<table class="' + theme + '">';
// table head
if (enableHeader) {
str += '<thead><tr>';
for (var index in array[0]) {
str += '<th scope="col">' + index + '</th>';
}
str += '</tr></thead>';
}
// table body
str += '<tbody>';
for (var i = 0; i < array.length; i++) {
str += (i % 2 == 0) ? '<tr class="alt">' : '<tr>';
for (var index in array[i]) {
str += '<td>' + val(array[i][index]) + '</td>';
}
str += '</tr>';
}
str += '</tbody>'
str += '</table>';
return str;
}
Any help is appreciated
I hope i understood you correctly but this should do it.
It alerts the content of the td with the name ID of the clicked tr.
$('tr').live('click',function(){
alert( $(this).find('td[name="ID"]').html() );
});
To find the td via the th with text ID you could do this:
var index = $('yourtable th:contains("ID")').index();
alert( $('.selectedRow td:eq('+index+')').html() );
What I would do though is to save the ID in the TR's data object so you won't have to pull it out the td but can access it directly, like this:
[...]
<tr data-id="26"><td>.....</td></tr>
[...]
then you can access it like that:
$('.selectedRow').data('id');

Categories