get values from table as key value pairs with jquery - javascript

I have a table:
<table class="datatable" id="hosprates">
<caption> hospitalization rates test</caption> <thead>
<tr>
<th scope="col">Funding Source</th> <th scope="col">Alameda County</th> <th scope="col">California</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Medi-Cal</th>
<td>34.3</td>
<td>32.3</td>
</tr>
<tr>
<th scope="row">Private</th>
<td>32.2</td>
<td>34.2</td>
</tr>
<tr>
<th scope="row">Other</th>
<td>22.7</td>
<td>21.7</td>
</tr>
</tbody>
</table>
i want to retrieve column 1 and column 2 values per row as pairs that end up looking like this [funding,number],[funding,number]
i did this so far, but when i alert it, it only shows [object, object]...
var myfunding = $('#hosprates tbody tr').each(function(){
var funding = new Object();
funding.name = $('#hosprates tbody tr td:nth-child(1)').map(function() {
return $(this).text().match(/\S+/)[0];
}).get();
funding.value= $('#hosprates tbody tr td:nth-child(2)').map(function() {
return $(this).text().match(/\S+/)[0];
}).get();
});
alert (myfunding);

var result = $('#hosprates tbody').children().map(function () {
var children = $(this).children();
return {
name: children.eq(0).text(),
value: children.eq(1).text()
};
}).get();
This will build an array in the form:
[
{ name : "...", value: "..." },
{ name : "...", value: "..." },
{ name : "...", value: "..." }
]
etc
To get the name of the first row, use:
alert(result[0].name);
For the value:
alert(result[0].value);
Edit: if you want the result EXACTLY as you specify:
var result = $('#hosprates tbody').children().map(function () {
var children = $(this).children();
return "[" + children.eq(0).text() + "," + children.eq(1).text() + "]"
}).get().join(",");

Try this then (demo):
var funding = $('#hosprates tbody tr').map(function(){
return [[ $(this).find('th').eq(0).text() , // find first and only <th>
$(this).find('td').eq(0).text() ]]; // find first <td> in the row
}).get();
alert(funding); // Output: Medi-Cal,32.3,Private,34.2,Other,21.7
The alert display only shows the data inside the array, it is actually formatted like this:
[["Medi-Cal", "32.3"], ["Private", "34.2"], ["Other", "21.7"]]
So you could get the Medi-Cal data like this:
alert(funding[0][0] + ' -> ' + funding[0][1]); // output: Medi-Cal -> 34.3

Related

Build an array of objects with two key/value pairs

I have to build an array like this :
[{'test1': 't1', 'test2' :'t2'},
{'test3' :'t3', 'test4': 't4' },
{'test5': 't5', 'test6' :'t6'},
{'test7' :'t7' , 'test8': 't7' }]
It will be an array of objects.
The object will have always have two key/value pairs.
Key and values will be dynamic.
I have to loop through the object below to build the array:
In the end, I have got to build a table out of the array, which will look like this:
It has to be a 2-columns table, with the key and value.
HTML:
<table class="detailList" >
<tbody>
<tr></tr>
<tr>
<th class="labelCol" scope="row"> <label>test1</label> </th>
<td class="dataCol"> t1</td>
<th class="labelCol" scope="row"> <label>test2</label> </th>
<td class="dataCol"> t2</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test3</label> </th>
<td class="dataCol"> t3</td>
<th class="labelCol" scope="row"> <label>test4</label> </th>
<td class="dataCol"> t4</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test5</label> </th>
<td class="dataCol"> t5</td>
<th class="labelCol" scope="row"> <label>test6</label> </th>
<td class="dataCol"> t6</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test7</label> </th>
<td class="dataCol"> t7</td>
<th class="labelCol" scope="row"> <label>test8</label> </th>
<td class="dataCol"> t7</td>
</tr>
</tbody>
</table>
Any idea how to do this?
Here is how I would create that table:
Working jsFiddle
var testObject = {
some_key: {
key1: '1',
key2: '2',
key3: '3',
}
};
var elements = [];
var last = null;
// loop over the keys in the object in question
$.each(testObject.some_key, function(key, value) {
var item = '<th class="labelCol" scope="row"><label>' + key + '</label></th><td class="dataCol">' + value + '</td>';
if (!last) { // if no last item, set this row to last dont add to the array of elements just yet, we need the other two columns first
last = item;
} else {
// if we already have a last, add these two columns to it, then add it to our array of elements
elements.push(last + item);
last = null;
}
});
if (last) {
// at the end, if we still have a "last" hanging around, add two empty columns
var item = '<th class="labelCol" scope="row"><label></label></th><td class="dataCol"></td>';
elements.push(last + item);
}
// join the array wrapping each set of 4 columns with a tr
var rows = '<tr>' + elements.join('<tr></tr>') + '</tr>';
$('.detailList tbody').html(rows);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="detailList">
<tbody>
</tbody>
</table>
What a crazy requirement. I like it. Here's my take on it. (Didn't test it)
var twoPairArray = []; //array to be returned
var twoPairObj = {}; //temp obj for manipulation
for(var key in targetObj) //target obj has the keys to be processed
{
if(Object.keys(twoPairObj).length == 2) //does temp obj have enough keys?
{
twoPairArray.push(JSON.parse(JSON.stringify(twoPairObj))); //sloppy clone of temp obj
twoPairObj = {}; //reset the temp obj.
}
twoPairObj[key] = targetObj[key]; //temp obj being manipulated into this craziness
}

Create an array of objects by iterating through table rows

I have an HTML table and I want to iterate through its rows and create a collection or lets say an "array of objects".
For example:
<table id="tbPermission">
<tr>
<th>User ID</th>
<th>User Name</th>
</tr>
<tr>
<td>1</td>
<td>Test1</td>
</tr>
</table>
I want to create a collection as below:
var trArray = [];
$('#tbPermission tr').each(function () {
var tdArray = [];
$(this).find('td').each(function () {
// I want to create the array of objects here …
tdArray.push();
});
// Final array
trArray.push(tdArray);
});
The arrays may be like below:
tdArray : {'UserID' : '1', 'UserName' : 'Test1'};
and:
trArray : [
{'UserID' : '1', 'UserName' : 'Test1'},
{'UserID' : '2', 'UserName' : 'Test2'}
]
Try this code
var trArray = [];
$('#tbPermission tr').each(function () {
var tr =$(this).text(); //get current tr's text
var tdArray = [];
$(this).find('td').each(function () {
var td = $(this).text(); //get current td's text
var items = {}; //create an empty object
items[tr] = td; // add elements to object
tdArray.push(items); //push the object to array
});
});
Here, I just created an empty object, filled object with references of tr and td, the added that object to the final array.
adding a working jsfiddle
This solution relies on adding thead and tbody elements which is a good idea anyways since it indicates to the browser that the table actually is a "data" table and not presentational.
jQuery has a .map() function. map is a basic function where you take an array and then replace the values with a the return value of a callback function - which results in a new array.
$([1,4,9]).map(function(){ return Math.sqrt(this) });
// [1, 2, 3]
.toArray converts the array like jQuery object we get into a "true array".
jQuery(function(){
var $table = $("#tbPermission");
var headers = $table.find('thead th').map(function(){
return $(this).text().replace(' ', '');
});
var rows = $table.find('tbody tr').map(function(){
var result = {};
var values = $(this).find('>td').map(function(){
return $(this).text();
});
// use the headers for keys and td values for values
for (var i = 0; i < headers.length; i++) {
result[headers[i]] = values[i];
}
// If you are using Underscore/Lodash you could replace this with
// return _.object(headers, values);
return result;
}).toArray();
// just for demo purposes
$('#test').text(JSON.stringify(rows));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tbPermission">
<thead>
<tr>
<th>User ID</th>
<th>User Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Test1</td>
</tr>
</tbody>
</table>
<textarea id="test"></textarea>
If you for whatever reason cannot change the HTML you could use the index of the rows to differentiate between headers and rows of data:
var headers = $table.find('tr:eq(0) th').map(function(){
return $(this).text().replace(' ', '');
});
var rows = $table.find('tr:gt(0)').map(function(){
// ...
});
I would suggest changing your html slightly.
<table id="tbPermission">
<tr>
<th>User ID</th>
<th>User Name</th>
</tr>
<tr>
<td class="userid">1</td>
<td class="username">Test1</td>
</tr>
</table>
Then in your javascript when you want to get all the elements as an array you could do.
var userIdArray = $('#tbPermission .userid').map(function(userid){ return $(userid).html(); }).toArray();
This will find all elements with a class userid on the table, collect just the values, and .toArray() that result to get a basic javascript array. You can then take that and manipulate it into whatever json structure you want, or you could possibly create your json object inside that map function.
Check the console, you will get an array with the desired objects
var arr = [];
$('#tbPermission tr:not(.header)').each(function() {
var that = $(this);
var id = that.find('td').eq(0).text();
var name = that.find('td').eq(1).text();
var obj = { 'userId': id , 'userName': name };
arr.push(obj);
});
console.log(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="tbPermission">
<tr class="header">
<th>User ID</th>
<th>User Name</th>
</tr>
<tr>
<td>1</td>
<td>Test1</td>
</tr>
<tr>
<td>2</td>
<td>Test2</td>
</tr>
</table>
It's a bit tricky based on the given structure. You may have to modify the HTML a bit to map cells to headers, like below.
var myArray = [];
$("#tbPermission").find("td").each(function() {
var $this = $(this), obj = {};
obj[$this.data("column")] = $this.text();
myArray.push(obj);
});
alert ( JSON.stringify(myArray) );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="tbPermission">
<tr>
<th>User ID</th>
<th>User Name</th>
</tr>
<tr>
<td data-column="User ID">1</td>
<td data-column="User Name">Test1</td>
</tr>
</table>
Please give in some time to learn about Array.push() and Objects in Javascript. Hope that helps.

Filtering table rows upon Search

I am trying to filter the rows of a table to display the results of entered text in the search bar. The code below does the job but for some reason filters the column headings as well.
$('#search').keyup(function () {
var data = this.value.split(" ");
var rows = $(".Info").find("tr").hide();
if(this.value ==""){
rows.show();
return;
}
rows.hide();
rows.filter(function(i,v){
var t = $(this);
for (var d = 0; d < data.length; d++) {
if (t.is(":Contains('" + data[d] + "')")) {
return true;
}
}
return false;
}).show();
});
HTML
<input type = "search" name = "search" id = "search">
<table style ="width:95%" class = "Info">
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
</table>
The user adds rows which is why i haven't written any HTML for it.
Any help would be appreciated. Thanks in advance
http://jsfiddle.net/szjhngwm/
It looks like you need to filter using tbody
<table style ="width:95%" class = "Info">
<thead>
<tr>
<th>Select </th>
<th>Name</th>
<th>Number</th>
<th>Date</th>
</tr>
<thead>
<tbody>
</tbody>
</table>
var rows = $(".Info tbody tr").hide();
Another way to do this would be to use jQuery's :gt() selector.
The only thing that would change is this line:
var rows = $(".Info").find("tr:gt(0)").hide();
Notice the addition of :gt(0) to your tr.

toggle between adding and removing an element

This is a Fiddle Example(updated) of adding extra rows to the tablesorter via AJAX
I'm trying to add a function that allows people to toggle between adding and removing the same element on click. Like when you click on Class A, if it doesn't exist in the table, it will be added to the table, if exists, removed and return false. I came up with this code to check if the button's data attribute matches a row's class which is distinctive as it uses item.title from their own JSON file.
$('.area button').click(function(){
var dataterm = $(this).data('term');
if($('.tablesorter tbody tr.'+dataterm).length)
{
return false;
$('.tablesorter tbody tr.'+dataterm).remove();
}
But it isn't working. Could anyone show me how to do that?
var ajax_request;
function add_Data() {
$('.area button').click(function(){
var dataterm = $(this).data('term');
if($('.tablesorter tbody tr.'+dataterm).length)
{
return false;
$('.tablesorter tbody tr.'+dataterm).remove();
}
var source = $(this).data('feed');
$.ajax({
url: source,
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title,
year = item.year,
job = item.Job,
education = item.Education,
background = item.Background,
ingredient = item.Ingredient;
$(".tablesorter tbody").append('<tr style="display:table-row;" class="'+title+' trremove lastadded' + $(".tablesorter tr.trremove").length + '"><td>'+education+'</td><td>'+background+'</td><td>'+job+'</td><td>'+ingredient+'</td><td>'+year+'</td><td>'+background+'</td><td>'+year+'</td></tr>');
});
},
});
$("table").trigger("update");
var sorting = [[2,1],[0,0]];
$(".tablesorter").trigger("sorton",[sorting]);
});
return false;
};
add_Data();
$('.undo').click(function(){
$('.lastadded' + ($(".tablesorter tr.trremove").length - 2)).remove();
});
$('.remove').click(function(){
$('.trremove').remove();
$(".tablesorter").trigger("update");
});
HTML
<div class="area"><button data-term="A">Class A</button></div>
<div class="area"><button data-term="C">Class C</button></div>
<div class="area"><button data-term="D">Class D</button></div>
<table class="tablesorter" cellspacing="1">
<thead>
<tr>
<th style="visibility:hidden;">first name</th>
<th>first name</th>
<th>last name</th>
<th>age</th>
<th>total</th>
<th>discount</th>
<th>date</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
You have a return false before executing your .remove() method on the found rows.
It should be
if($('.tablesorter tbody tr.'+dataterm).length)
{
$('.tablesorter tbody tr.'+dataterm).remove();
} else {
...
}
Here's the update to your Fiddle.

JQuery, Find results in table column

Im trying to find the results in a table column if its set in my function below, most of this was setup by someone else, ive just added some extras into it, my final one is searching 1 column only by name set in the thead but alas in its current edition nothing happens at all :|
thanks for any help
USAGE
<a href='javascript:searchTable("Bob", "table",1,"Name");'>Test</a>
TABLE
<table id="table" class="table">
<thead>
<tr>
<th id="blank"> </th>
<th id="Name">Name</th>
<th id="Dept">Department</th>
<th id="JobTitle">Job Title</th>
</tr>
</thead>
<tbody>
<tr>
<td> </td>
<td>Bob</td>
<td>IT</td>
<td>IT Support</td>
</tr>
<tr>
<td> </td>
<td>Fred</td>
<td>Finance</td>
<td>Finance Man</td>
</tr>
</tbody>
</table
FUNCTION
function searchTable(inputVal, tablename,starts, column) {
var table = $(tablename);
table.find('tr:not(.header)').each(function (index, row) {
if (column != '') {
//Columnname
var Cells = $(row).find('td').eq(column);
} else {
//AllCells
var Cells = $(row).find('td');
}
if (Cells.length > 0) {
var found = false;
Cells.each(function (index, td) {
if (starts == 1) {
var regExp = new RegExp((starts ? '^' : '') + inputVal, 'i');
} else {
var regExp = new RegExp(inputVal, 'i');
}
if (regExp.test($(td).text())) {
found = true;
return false;
}
});
if (found == true) $(row).show().removeClass('exclude'); else
$(row).hide().addClass('exclude');
}
});
}
As you're passing the column as a string, you need get the corresponding elements index:
var Cells = $(row).find('td:eq(' + $('#' + column).index() + ')');
The above presumes that you're matching based on the id, if you're matching based on the text within the <th> you could use the :contains selector:
$(row).find('td:eq(' + $(table.prop('id') + ' th:contains(' + column + ')').index() + ')');
If you can control and modify the function calls, the best thing to do would be to just pass the elements index directly to the function:
javascript:searchTable("Bob", "table", 1, 1); <-- Would be the "Name" column
That way, you won't have to do any of the above.
By the way, your table selector is incorrect based on your comment, not sure if that's just a typo on your part?
var table = $(tablename);
Should be:
var table = $('#' + tablename);
I am not sure what you are trying to control but you can use this to loop through rows and get the values of cells.
$("#table>tbody>tr").each(function(){
var name= $(this).children("td").eq(1).html();//Name
var department= $(this).children("td").eq(2).html();//Department
var jobTitle= $(this).children("td").eq(2).html();//Job Title
alert(name);
});
http://jsbin.com/uvefud/1/edit
Edit:
You can try this searchTable function.
function searchTable(name,tableName,row,column){
var $Tds= $("#"+tableName+">tbody>tr").eq(row-1).children("td");
if(column=="Name"){
$Tds.eq(1).html(name);
}
else if(column=="Dept"){
$Tds.eq(2).html(name);
}
else if(column=="JobTitle"){
$Tds.eq(3).html(name);
}
}
http://jsfiddle.net/W9zpq/2/
Usage: This will update the name column of 2nd row of tbody to 'Bob'
searchTable("Bob", "table",2,"Name")

Categories

Resources