HTML table data into arrays via jQuery - javascript

I want to extract data from an html table like
<table>
<tr>
<th> Header1 </th>
<th> Header2 </th>
<th> Header3 </th>
</tr>
<tr>
<td> Value 1,1 </td>
<td> Value 2,1 </td>
<td> Value 3,1 </td>
</tr>
... rows ...
</table>
and get arrays:
an array for the headers
a 2d array for the column values (or an array for each column)
How can I do this using jQuery?
I don't care to serialize it, or put it into a JSON object because I want to use it to render a chart.
related General design question:
at the moment I have something like
1. ajax query returns html table
2. use jQuery to get values from html table
3. render chart
does it make more sense to throw a JSON object back from the ajax query and then render a table and a chart from there?

demo updated http://jsfiddle.net/ish1301/cnsnk/
var header = Array();
$("table tr th").each(function(i, v){
header[i] = $(this).text();
})
alert(header);
var data = Array();
$("table tr").each(function(i, v){
data[i] = Array();
$(this).children('td').each(function(ii, vv){
data[i][ii] = $(this).text();
});
})
alert(data);

Something like this?
$(function() {
var headers = $("span",$("#tblVersions")).map(function() {
return this.innerHTML;
}).get();
var rows = $("tbody tr",$("#tblVersions")).map(function() {
return [$("td:eq(0) input:checkbox:checked",this).map(function() {
return this.innerHTML;
}).get()];
}).get();
alert(rows);
});

yet another way of doing it
var headers = jQuery('th').map(function(i,e) { return e.innerHTML;}).get();
var datas = []
jQuery.each(jQuery('tr:gt(0)'), function(i,e ) {
datas.push(jQuery('td', e).map(function(i,e) {
return e.innerHTML;
}).get()
);
});

Something along the lines of:
var thArray = new Array();
var contentArray = new Array();
$('th').each(function(index) {
thArray[index] = $(this).html();
})
$('tr').each(function(indexParent) {
contentArray['row'+indexParent] = new Array();
$(this).children().each(function(indexChild) {
contentArray['row'+indexParent]['col'+indexChild] = $(this).html();
});
});
This gives you two arrays, thArray which is an array of your headings and contentArray which is a 2d array containing rows and columns: contentArray['row1']['col0'] returns " Value 1,1"
Actually, contentArray contains the th's as well... referenced 'row0'

does it make more sense to throw a JSON object back from the ajax query and then render a table and a chart from there?
Yes, absolutely. Return JSON in response to your AJAX request, then you can render the table using something like jQuery Templates and use the same underlying data to generate your chart as well.

Here's a modification of Jerome Wagner's answer that uses recursive maps instead of a map inside an 'each':
http://jsbin.com/oveva3/383/edit
var headers = $("th",$("#meme")).map(function() {
return this.innerHTML;
}).get();
var rows = $("tbody tr",$("#meme")).map(function() {
return [$("td",this).map(function() {
return this.innerHTML;
}).get()];
}).get();

I'm tinkering with the same thing over here, but I prefer iterating through all tables and writing the header and body arrays into properties of each table, so here's my modification to the original answer:
$(function() {
$("table").each(function(){
var $table = $(this),
$headerCells = $("thead th", $(this)),
$rows = $("tbody tr", $(this));
var headers = [],
rows = [];
$headerCells.each(function(k,v) {
headers[headers.length] = $(this).text();
$table.prop("headAry", headers);
});
$rows.each(function(row,v) {
$(this).find("td").each(function(cell,v) {
if (typeof rows[cell] === 'undefined') rows[cell] = [];
rows[cell][row] = $(this).text();
$table.prop("bodAry", rows);
});
});
console.log($(this).prop('headAry'));
console.log($(this).prop('bodAry'));
});
});
JSbin

Use this line of code:
var arrays = [];
$('table').eq(0).find('tr').each((r,row) => arrays.push($(row).find('td,th').map((c,cell) => $(cell).text()).toArray()))

I would think it would make more sense to get a json array back from the ajax call and generate your table/chart from that. With jquery templates this isn't hard at all.

Related

how to append value in select tag inside dynamic table

im adding table row data using json response. here is my code
var i;
for (i = 0; i < result.length; i++) {
$.get('LoadserviceSplit', {
"sectcode" : result[i]
},
function (jsonResponse) {
if (jsonResponse != null) {
var table2 = $("#table_assign");
$.each(jsonResponse, function (key, value) {
var rowNew = $("<tr><td></td><td></td><td></td><td></td><td></td><td></td></tr>");
rowNew.children().eq(0).text(value['serviceId']);
rowNew.children().eq(1).text(value['title']);
rowNew.children().eq(2).html('<input type="text" id="date_set" name="date_set"/>');
rowNew.children().eq(3).html('<input type="text" id="date_set1" name="date_set1"/>');
rowNew.children().eq(4).html('<input type="text" id="date_set2" name="date_set2"/>');
rowNew.children().eq(5).html('<select class="status1" id="status1">');
rowNew.appendTo(table2);
});
}
});
var pass_unit_code = "001";
$.get('LoadDivisionCodeServlet', { //call LoadDivisionCodeServlet controller
unitCode : pass_unit_code //pass the value of "sample" to unitCode:
}, function (jsonResponse) { //json response
var select = $('#status1'); //select #status1 option
select.find('option').remove(); //remoev all item in #divcode option
$.each(jsonResponse, function (index, value) {
$('<option>').val(value).text(value).appendTo(select); //response from JSON in array value{column:value,column:value,column:value}
});
});
}
it works fine except the select tag part. only the first row of table have value. the rest has no value. i want all drop-down list inside the table has same value.. can anyone help me about this.
Take a look at
rowNew.children().eq(5).html('<select class="status1" id="status1">');
You're creating new select elements in a $.each and assigning the same id, that is status1 to all of them.
Then you're selecting the select element that has an id of status1 like
var select = $('#status1'); //select #status1 option
Therefore, only the first select element will be selected.
EDIT:
Your question is not completely clear.
However, this is how you can add different Id for select inside each of your <td>
Replace this
rowNew.children().eq(5).html('<select class="status1" id="status1">');
With something like
rowNew.children().eq(5).html('<select class="status1" id="status'+key+'">');
So this will have different Ids.

Accessing row element of table in Javascript

This is my first attempt in Javascript, so may be this is fairly easy question.
I need to access row element of a table, each row contains checkbox and two other column. If checkbox is checked, i need to get the id of checkbox.
I made following attempt but element_table.rows returns undefined, therefore i could not proceed. I debugged using Inspect element tool of eclipse and found element_table contains the rows.
Please suggest where I am making a mistake.
Javascript code:
function myfunction3(){
var element_table = document.getElementsByName('collection');
var element_tableRows = element_table.rows;
var selectedTr = new Array();
var data = "";
for(var i =0 ; element_tableRows.length;i++)
{
var checkerbox = element_tableRows[i].getElementsByName('checkmark');
if(checkerbox.checked){
selectedTr[selectedTr.length] = element_tableRows[i].getAttribute("name");
data = data + element_tableRows[i].getAttribute("name");
}
}
var element_paragraph = document.getElementsByName('description');
element_paragraph.innerHTML = data;
}
html code:
<table name="collection" border="1px">
<tr name="1">
<td><input type="checkbox" name="checkmark"></td>
<td>Tum hi ho</td>
<td>Arjit singh</td>
</tr>
<tr name="2">
<td><input type="checkbox" name="checkmark"></td>
<td>Manjha</td>
<td>Somesh</td>
</tr>
<tr name="3">
<td><input type="checkbox" name="checkmark"></td>
<td>Ranjhana</td>
<td>A.R Rehman</td>
</tr>
</table>
<input type="button" value="Check" onclick="myfunction3()">
here's a working version
function myfunction3(){
var element_table = document.getElementsByName('collection');
var element_tableRows = element_table[0].rows;
var selectedTr = new Array();
var data = "";
for(var i =0 ; i < element_tableRows.length;i++)
{
var checkerbox = element_tableRows[i].cells[0].firstChild;
if(checkerbox.checked){
//selectedTr[selectedTr.length] = element_tableRows[i].getAttribute("name"); //not sure what you want with this
data = data + element_tableRows[i].getAttribute("name");
}
}
var element_paragraph = document.getElementsByName('description');
element_paragraph.innerHTML = data;
alert(data);
}
http://jsfiddle.net/eZmwy/
jsfiddle for your example, your problem is mainly at when you getElementsByName you need to specify the index, also not that not all getElement methods are available in the table
i would also suggest you learn jQuery, this makes life easier, also not sure why you want to display the data as 1,2,3 the name on the tr... seems pretty strange to me
Actually this line
var element_table = document.getElementsByName('collection');
will return collection of elements. If you are sure that you have exactly one table with the specified name, try this approach:
var element_table = document.getElementsByName('collection')[0];
actually if you are using jQuery (very recommanded )
you can do something like
var idsArray = [];
$("[name=collection] tr td [type=checkbox]:checked").parent().each(function() {
idsArray .push($(this).attr('name'))
});
this answer related only to jQuery use (which is same as javascript only more compiled.)

If <td> has the largest int, in its <tr> add css class to <td> - jquery

Ive got a table of data, and I'm trying to at a glance look over it and find the highest number on each row.
To do this I'm adding a css class called highest to the highest <td> like this
<tr>
<td>4.2</td>
<td class="highest">5.0</td>
<td>2.9</td>
</tr>
with this css
td.highest {font-weight:bold;}
But this is all hardcoded, I'm trying to work out how to write this using jquery, but I'm pretty new to js and not really sure were to start, I was looking at using Math.max but as I can tell thats to be used on arrays, rather that reading html, any ideas ?
I've made a jsfiddle here - http://jsfiddle.net/pudle/vEUUQ/
First bash - shorter (and potentially more efficient) answers may be available...
$('tr').each(function() {
var $td = $(this).children();
// find all the values
var vals = $td.map(function() {
return +$(this).text();
}).get();
// then find their maximum
var max = Math.max.apply(Math, vals);
// tag any cell matching the max value
$td.filter(function() {
return +$(this).text() === max;
}).addClass('highest');
});
demo at http://jsfiddle.net/alnitak/DggUN/
Based upon this structure:
<table>
<tr>
<td>4.2</td>
<td>5.0</td>
<td>2.9</td>
</tr>
</table>
You can use JS/jQuery and do:
var highest = 0;
$("table tr td").each(function() {
var current = $(this).text();
if (current > highest) {
highest = current;
$(".highest").removeClass();
$(this).addClass('highest');
}
});
http://jsfiddle.net/syU82/
The easiest thing I can think of is to use http://underscorejs.org/#max or http://lodash.com/docs#max and pass in a function that filters for this.
var result = _.max($("td"),function(td){ return parseFloat($(td).text()); });
result.addClass("highest");
Otherwise you can do it the long way:
var result,max 0;
$("td").filter(function(){
var myval = parseFloat($(this).text());
if(myval > max){
result = this;
max = myval;
}
});
result.addClass("highest");
Yet another solution, not as good as some of the others though.
$('tr').each(function() {
var $highest_el;
var highest_num;
$('td', this).each(function() {
if ( $highest_el === undefined || parseFloat($(this).text()) > highest_num ) {
$highest_el = $(this);
highest_num = $(this).text();
}
});
$highest_el.addClass('highest');
});
jsFiddle: http://jsfiddle.net/hRJLQ/2/

if ID is missing fill the rows in another hiddenfield with jquery

I have one Table that is named CustomPickedTable, this Table have rows with attribute such as <td Data-question-id="5">Example</td> and some of the rows do not have any attribute at all. just <td>example</td>.
I want to do be able to sort em into different hiddenfields, these are my hiddenfields:
#Html.HiddenFor(model => model.SelectedCustomQuestions, new { #id = "SelectedQuestionsWithAttr" })
#Html.HiddenFor(model => model.SelectedQuestions, new { #id = "SelectedQuestionsWithNoAttr" })
the code that I have right now is that all rows with attribute "data-question-id" gets filled to SelectedQuestionsWithAttr that is my hiddenfield for rows with attributes.
But I want that my Jquery code also fills those rows with no attributes gets filled to my SelectedQuestiosnWithNoAttr hiddenfield.
This is the code for Just filling SelectedQuestionsWithAttr hiddenfield:
var selectedQuestionsWithAttr = $("#SelectedQuestionsWithAttr");
var currentIds = new Array();
$("#CustomPickedTable").find("td").each(function () {
var clickedId = $(this).attr("data-question-id");
currentIds.push(clickedId);
});
selectedQuestionsWithAttr.val(currentIds.join(","));
$("form").submit();
}
Is there any solutions that can I add to my jquery code for this?
Thanks in Advance
You would need to add something onto the <td> tags to be able to identify them:
<td id="noAttr#(Model.SelectedQuestions.IndexOf(variable))">
Then the jQuery would be:
var $qWithAttr = $("#SelectedQuestionsWithAttr");
var $qWithoutAttr = $("#SelectedQuestionsWithNoAttr");
var currentIds = new Array();
var missingIds = new Array();
$("#CustomPickedTable td[data-question-id]").each(function () {
currentIds.push($(this).attr("data-question-id"));
});
$("#CustomPickedTable td:not([data-question-id])").each(function () {
missingIds.push($(this).attr("id"));
});
$qWithAttr.val(currentIds.join(","));
$qWithoutAttr.val(missingIds.join(","));
$("form").submit();

get data of selected rows in slickgrid

I have a slickgrid in which some rows are hidden by a filter (DataView).
When I now call the getSelectedRows method of the grid I get the indices of the visibly selected rows. But I need the actual data of the selected rows.
You must do something like this:
var selectedData = [],
selectedIndexes;
selectedIndexes = _grid.getSelectedRows();
jQuery.each(selectedIndexes, function (index, value) {
selectedData.push(_grid.getData()[value]);
});
Right now the selectedData variable contains data for selected rows.
You have a mistake. It needs to be "getDataItem" and not "getData".
var selectedData = [],enter code here`selectedIndexes;
selectedIndexes = _grid.getSelectedRows();
jQuery.each(selectedIndexes, function (index, value) {
selectedData.push(_grid.getDataItem(value));
});
hObjMarcado = ( grid.getSelectedRows());
for( var a_id in hObjMarcado ) {
vres.push( dataview.getItem( hObjMarcado[a_id] ));
//la opcion getItem obtiene el elemento especifico,
//aun con filtro.
}
return vres;
You can also use this line in the .each loop to pull the data from the dataView instead of using getData() from the grid object, since that seems to be inconsistent depending on the fork:
var selectedData = [],
selectedIndexes;
selectedIndexes = _grid.getSelectedRows();
jQuery.each(selectedIndexes, function (index, value) {
selectedData.push(_dataView.getItemById(value));
});
If you access grid from other control like . click button
var selectRow = gridInstance.getSelectedRows();
alert(gridInstance.getDataItem(selectRow).columnName)

Categories

Resources