I'm receiving an array of objects in form of a json file, and using ajax to display certain key-value pairs in a table. My next step is to sort the rendered table, but I'm unsure of how to proceed.
<div id="data-table">
<table id="html-data-table">
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</table>
</div>
Javascript code which creates the table:
newData.map(row => {
let newRow = document.createElement("tr"); // new row is created
Object.values(row).map((value) => {
//console.log(value);
let cell = document.createElement("td"); // new data for the row is added
cell.innerText = value;
newRow.appendChild(cell);
})
mytable.appendChild(newRow);
});
I want to sort this both columns individually. What method can I use?
You can use Array.sort() to sort your data, in this example I added two buttons to handle sorting by name and age:
const newData = [
{ name: "dave", age: 22 },
{ name: "charlie", age: 32 },
{ name: "eve", age: 19 },
{ name: "alice", age: 27 },
{ name: "bob", age: 20 }
]
const mytable = document.querySelector("#html-data-table tbody")
const btnSortName = document.getElementById("sortName")
const btnSortAge = document.getElementById("sortAge")
// RENDER UNSORTED TABLE
renderTable(newData)
btnSortName.addEventListener('click', (e) => {
const sorted = newData.sort((a,b) => a.name.localeCompare(b.name))
renderTable(sorted)
})
btnSortAge.addEventListener('click', (e) => {
const sorted = newData.sort((a,b) => a.age - b.age)
renderTable(sorted)
})
function renderTable(data) {
mytable.innerHTML = ''
data.map(row => {
let newRow = document.createElement("tr"); // new row is created
Object.values(row).map((value) => {
//console.log(value);
let cell = document.createElement("td"); // new data for the row is added
cell.innerText = value;
newRow.appendChild(cell);
})
mytable.appendChild(newRow);
});
}
<div id="data-table">
<table id="html-data-table">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<button id="sortName">Sort by Name</button>
<button id="sortAge">Sort by Age</button>
Here is a method of sorting the table in place, independent of any generating data structures. The only additionally required information is the sortmode array that specifies whether a text sort or a numeric sort is wanted for a particular column.
const data=[{name:"Harry",age:32, height:183},{name:"Hermione",age:30, height:175},{name:"Ron",age:31,height:187},{name:"Hagrid",age:53,height:180},{name:"Ginny",age:27,height:170},{name:"Dumbledore",age:273,height:185}],
sortmode=[0,1,1]; // 0: text, 1: numeric
mytable=document.querySelector("#data-table tbody");
// fill table: code from OP
data.map(row => {
let newRow = document.createElement("tr"); // new row is created
Object.values(row).map((value) => {
//console.log(value);
let cell = document.createElement("td"); // new data for the row is added
cell.innerText = value;
newRow.appendChild(cell);
})
mytable.appendChild(newRow);
});
// sorting: my code
document.querySelector("#data-table thead").onclick=ev=>{
let col=[...ev.target.parentNode.children].indexOf(ev.target);
[...mytable.children]
.sort((a,b)=>
sortmode[col]
? a.children[col].textContent - b.children[col].textContent
: a.children[col].textContent.localeCompare(b.children[col].textContent)
)
.forEach(tr=>mytable.append(tr))
}
td:nth-child(n+2) {text-align:right}
<div id="data-table">
Please click on the column headings to sort the table:
<table id="html-data-table">
<thead>
<tr><th>Name</th><th>Age</th><th>Height</th></tr>
</thead><tbody></tbody>
</table>
</div>
Related
I am trying to make a data table from user input. i found out this solution that i am making objects from user input and pushing them to an array. after that, I am doing a for loop to make td. but somehow those datas are re writing in the same raw. and previous raw datas are getiing replaced by new input datas.what I am doing wrong here and every time I am refreshing the page the array is getting empty how to prevent this help me out tnx.
const form = document.getElementById("form");
const tdbody = document.getElementById("data");
const carDatas = [];
let count = 0;
class Car {
constructor(plate, carMaker, carModel, carOwner, carPrice, carColor) {
(this.plate = plate),
(this.carMaker = carMaker),
(this.carModel = carModel),
(this.carOwner = carOwner),
(this.carPrice = carPrice),
(this.carColor = carColor);
}
}
form.addEventListener("submit", (e) => {
const plate = document.getElementById("plate").value;
const carMaker = document.getElementById("carMaker").value;
const carModel = document.getElementById("carModel").value;
const carOwner = document.getElementById("carOwner").value;
const carPrice = document.getElementById("carPrice").value;
const carColor = document.getElementById("carColor").value;
const carDetails = new Car(
plate,
carMaker,
carModel,
carOwner,
carPrice,
carColor
);
carDatas.push(carDetails);
for (let i = 0; i < carDatas.length; i++) {
document.getElementById("data").innerHTML = document.createElement(
"tr"
).innerHTML = `<td>${carDatas[i].plate} </td>
<td>${carDatas[i].carMaker} </td>
<td>${carDatas[i].carModel} </td>
<td>${carDatas[i].carOwner} </td>
<td>${carDatas[i].carPrice} </td>
<td>${carDatas[i].carColor} </td> `;
}
e.preventDefault();
});
here is my html for table
<div class="database">
<h1>Cars Database</h1>
<table>
<thead>
<tr>
<th>LICENCE</th>
<th>MAKER</th>
<th>MODEL</th>
<th>OWNER</th>
<th>PRICE</th>
<th>COLOR</th>
</tr>
</thead>
<tbody id="data"></tbody>
</table>
</div>
Your for loop is bad!
I don't know if this part of your code is working, but if you have an array of objects you should see a function for arrays that is called map
arr.map((object) => {
return <td>{object.plate}</td>
})
this function is example, try to look for documentation
I use Vue 2.
I generate table from the collection:
<table class="table table-striped table-bordered">
<tbody>
<tr v-for="(type, typeIndex) in getAllUpgradeTypes" :key="typeIndex">
<td>
<imageDesc
style="margin-left: 10px"
:title="type"
:text="'Select an Option'"
:zoneId="selectedZone.id"
/>
</td>
</tr>
</tbody>
</table>
Currently, the table created with multiple rows, each row has only one column and shows one item inside the column.
My question how can I generate a table which will contain 3 columns per row?
There at least a couple of different patterns you could use for this. One involves rearranging your data before iterating it in the template, another doesn't. I'll show you both.
In both cases, use a data property to hold the number of columns:
data: () => ({
numCols: 3
})
Reorganize the data into a 2D array
Instead of one array with all your items, use a computed to reorganize the data into a multi-dimensional array of rows and columns:
computed: {
arrangedData() {
const arrangedData = [];
this.getAllUpgradeTypes.forEach((item, index) => {
if (index % this.numCols === 0) {
arrangedData.push([])
}
arrangedData[arrangedData.length - 1].push(item);
});
return arrangedData;
}
}
Iterate the data like this:
<table class="table table-striped table-bordered">
<tr v-for="(row, rowIndex) in arrangedData" :key="rowIndex">
<td v-for="(type, typeIndex) in row" :key="`${rowIndex}:${typeIndex}`">
{{ type }}
</td>
</tr>
</table>
Here's a demo:
new Vue({
el: "#app",
data: () => ({
getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'],
numCols: 3
}),
computed: {
arrangedData() {
const arrangedData = [];
this.getAllUpgradeTypes.forEach((item, index) => {
if (index % this.numCols === 0) {
arrangedData.push([])
}
arrangedData[arrangedData.length - 1].push(item);
});
return arrangedData;
}
}
});
td { width: 40px }
<div id="app">
<table class="table table-striped table-bordered">
<tr v-for="(row, rowIndex) in arrangedData" :key="rowIndex">
<td v-for="(type, typeIndex) in row" :key="`${rowIndex}:${typeIndex}`">
{{ type }}
</td>
</tr>
</table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
-or-
Calculate the number of rows
The other way involves using a computed to calculate the number of rows. It's less code, but then type gets an ugly syntax in the template:
computed: {
numRows() {
return Math.ceil(this.getAllUpgradeTypes.length / this.numCols);
}
}
Iterate the data like this:
<table class="table table-striped table-bordered">
<tr v-for="(row, indexRow) in numRows">
<td v-for="(col, indexCol) in numCols">
{{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }}
</td>
</tr>
</table>
Here's a demo:
new Vue({
el: "#app",
data: () => ({
getAllUpgradeTypes: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k'],
numCols: 3
}),
computed: {
numRows() {
return Math.ceil(this.getAllUpgradeTypes.length / this.numCols);
}
}
});
td { width: 40px; }
<div id="app">
<table>
<tr v-for="(row, indexRow) in numRows" :key="indexRow">
<td v-for="(type, indexCol) in numCols" :key="`${rowIndex}:${typeIndex}`">
{{ getAllUpgradeTypes[(indexRow * numCols) + indexCol] }}
</td>
</tr>
</table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
There are probably some variations on these options but I think the first is probably the best for the template clarity.
Here is my solution to a similar issue. I needed to generate a printable page and display information from a table in our database. The appearance of the page required me to have 3 fixed-size rows and 3 fixed-size columns per row.
I added styling to give it a grid-like appearance, but here is how I generated the table with page breaks after 3 rows:
This is where I have the table setup in the HTML (cshtml) file:
<table id="employee-table" class="m-auto">
</table>
Here is my JavaScript function which is located in an external JS file (don't forget to reference the file in your HTML if that's how you're setting it up)
function GeneratePrintablePDF(employeeData) {
document.getElementById('loader').classList.add('hidden'); //this is just the "loading" spinner for when the page is loading
dataContainer = document.getElementById('employee-table');
numberOfRows = employeeData.length / 3;
if (employeeData % 3 != 0) {
numberOfRows = Math.trunc(numberOfRows);
numberOfRows += 1;
}
var emp = 0;
do
{
for (var row = 1; row <= numberOfRows; row++) {
var tableRowDiv = document.createElement('div');
dataContainer.appendChild(tableRowDiv);
var tableRow = document.createElement('tr');
tableRowDiv.appendChild(tableRow);
for (var col = 1; col < 4; col++)
{
if (emp < employeeData.length) {
var tableCol = document.createElement('td');
tableCol.className = 'pdf-employee-box';
tableRow.appendChild(tableCol);
var empName = document.createElement('div');
empName.className = 'fw-bold';
empName.innerHTML = `${employeeData[emp].firstName} ${employeeData[emp].lastName}`;
tableCol.appendChild(empName);
var empPhoto = document.createElement('img');
var employeePhotoUrl = employeeData[emp].azurePhotoURL;
if (employeePhotoUrl == null) {
empPhoto.src = '/Images/lg_unavailable.jpg';
} else {
empPhoto.src = employeePhotoUrl;
}
var empPhotoOnError = document.createAttribute('onerror');
empPhotoOnError.value = "this.onerror=null;this.src='/Images/lg_unavailable.jpg';";
empPhoto.setAttributeNode(empPhotoOnError);
empPhoto.alt = 'Employee Photo';
empPhoto.className = 'employee-photo-pdf pdf-image';
tableCol.appendChild(empPhoto);
var empTitle = document.createElement('div');
empTitle.innerHTML = employeeData[emp].title != null ? `Title: ${employeeData[emp].title}` : 'Title: Unknown';
empTitle.className = 'pdf-details';
tableCol.appendChild(empTitle);
var empDept = document.createElement('div');
empDept.innerHTML = employeeData[emp].department != null ? `Department: ${employeeData[emp].department}` : 'Department: Unknown';
empDept.className = 'pdf-details';
tableCol.appendChild(empDept);
var empEmail = document.createElement('div');
empEmail.innerHTML = (employeeData[emp].emailAddress != null && !employeeData[emp].emailAddress.toLowerCase().includes('no ')) ? `Email: ${employeeData[emp].emailAddress}` : 'Email: Unknown/None';
empEmail.className = 'pdf-details';
tableCol.appendChild(empEmail);
var empStartDate = document.createElement('div');
empStartDate.innerHTML = employeeData[emp].startDate != null ? `Start Date: ${employeeData[emp].startDate}` : 'Start Date: Unknown';
empStartDate.className = 'pdf-details';
tableCol.appendChild(empStartDate);
var empLocation = document.createElement('div');
empLocation.innerHTML = employeeData[emp].location != null ? `Location: ${employeeData[emp].location}` : 'Location: Unknown';
empLocation.className = 'pdf-details';
tableCol.appendChild(empLocation);
if (col == 2) tableCol.className = tableCol.className + ' pdf-grid-lines';
emp++;
}
}
if (emp % 9 == 0) {
tableRowDiv.className += 'page-break-after';
}
}
} while (emp < employeeData.length)
}
I decided to calculate the number of rows I need based on how many employee records we have. So, if we have 436 employees, then I'm determining that I need 146 rows. So I'm programming it to generate the precise number of rows I need, and only put 3 items (columns) in each row. The 146th row in this case only has 1 record.
As you can see, I have the code in a loop only running until it reaches the last employee, so that it doesn't throw an index out of range exception.
This particular code is where I am telling the table to break to the next page, so that employee records aren't running over onto another page and splitting up the information.
if (emp % 9 == 0) {
tableRowDiv.className += 'page-break-after';
}
Here is the CSS that I'm referencing in an external CSS file:
#media print {
.page-break-after {
break-after: page;
}
}
I understand that I am by no means the ultimate programming kingpin, so there could be better or easier ways of doing this. However, this is how I made it work with my environment and it does exactly what I need it to do without using some framework or library.
I found in my research that many PDF generator frameworks, libraries, etc. now require licensing. So if generating a printable document is your goal, then this could work for you too. Anyways, good luck and I hope I have helped someone.
Hey i'm trying to get the id of the specific object so that i can send it to the backend for now. I'm having a hard time get the individual object and not the whole list at once.
If anything looks funky it's because I'm pretty new at this and it's been alot of trial and error
my javascript looks like this:
//waits for the html doc to be ready before atempting to run any js.
$(document).ready( () =>{
// jquery getting our json order data from API
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.find('.customer_name').text(item.customer_name);
$clone.find('.date').text(item.date);
$clone.find('.time').text(item.time);
$clone.find('.pickup').text(item.pickup);
$clone.find('.comments').text(item.comments);
$clone.find('.total').text(item.total + ' Kr.');
let foo = function(){
//gets id from object and sends it to backend using get method
};
// accept and cancel buttons
$clone.find('.order_status').html(
`<button id = "acceptOrder" type="button" onclick="${foo()}">Accept</button>` +
`<button id = "cancelOrder" type="button" onclick="${foo()})">Cancel</button>`
);
// loops through orders product name
let productsName = item.products.map(prod => `${prod.name}`);
$clone.find('.products').html(productsName.join('<br />'));
// loops through orders product price
let productsPrice = item.products.map(prod => `${prod.price} Kr.`);
$clone.find('.price').html(productsPrice.join('<br />'));
return $clone;
});
//appends to our frontpage html
$("#frontpage_new_ordertable tbody").append(rows);
});
});
This is the json data i get from my route.
{
id: "3JBBdJdBUP7QyDvCnmsF",
date: "30/04-2020",
time: "13:40:41",
total: 40,
products: [
{
name: "Caffe Latte",
price: 40
}
]
}
My html looks like this:
<!-- this is the table of new orders -->
<table id="frontpage_new_ordertable">
<tbody>
<tr>
<th>Customer</th>
<th>Date</th>
<th>Ordered at</th>
<th>Wished pickup time</th>
<th>Order</th>
<th>Comments</th>
<th>Price</th>
<th>Total</th>
<th>Order Status</th>
</tr>
</tbody>
<tfoot>
<tr>
<td class="customer_name"></td>
<td class="date"></td>
<td class="time"></td>
<td class="pickup"></td>
<td class="products"></td>
<td class="comments"></td>
<td class="price"></td>
<td class="total"></td>
<td class="order_status"></td>
</tr>
</tfoot>
</table>
After edit it looks like this. I'm not seeing the accept button
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.data("id", item.id);
$clone.find('.date').text(item.date);
$clone.find('.time').text(item.time);
$clone.find('.pickup').text(item.pickup);
$clone.find('.comments').text(item.comments);
$clone.find('.total').text(item.total + ' Kr.');
$(function() {$(document).on("click", ".acceptOrder", foo);
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
};
$clone.find('.order_status').html(
`<button type="button" class='acceptOrder">Accept</button>`
);
});
The relevant parts of the code are:
$(function() {
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
let foo = function(){
//gets id from object and sends it to backend using get method
};
$clone.find('.order_status').html(
`<button id="acceptOrder" type="button" onclick="${foo()}">Accept</button>`
);
return $clone;
});
//appends to our frontpage html
$("#frontpage_new_ordertable tbody").append(rows);
});
});
First step is to remove the duplicate id: and onclick=
$(function() {
$(document).on("click", ".acceptOrder", foo);
function foo() {
}
...
$clone.find('.order_status').html(
`<button type="button" class='acceptOrder">Accept</button>`
);
...
});
Now, clicking the Accept button will call 'foo' as an event, with this as the button. You can get the original JSON ID by either putting this on the button as a data-id or on the parent tr:
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
$clone.data("id", item.id);
then, in foo, you can get this as:
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
...
}
the alternative is to add to the button in the same way - I tend to use it on the tr as you'll probably need to get the tr anyway and it means it's available from any element (eg another button).
`<button type="button" data-id="${item.id}" ...
To include some more context:
$(document).ready(() =>{
// add event listener here
$(document).on("click", ".acceptOrder", foo);
// add the event handler at the top-level inside doc.ready
function foo() {
var btn = $(this);
var row = btn.closest("tr");
var id = row.data("id");
var name = row.find(".customer_name").text();
...
}
// original code
$.get("http://localhost:8888/orderslist", (data) => {
// loops through our orderlist api
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
// add ID to the row as a data-id
$clone.data("id", item.id);
// original code
$clone.find('.customer_name').text(item.customer_name);
...etc
// remove let foo =
// let foo = function(){
// update accept/cancel buttons
// accept and cancel buttons
$clone.find('.order_status').html(
`<button class="acceptOrder" type="button">Accept</button>` +
`<button class="cancelOrder" type="button">Cancel</button>`
);
Question 1 - So I am trying to do just a simple loop through my json array and create a new row for each of the objects in the array. For some reason I can't figure out, it is only printing the last object of the array to the DOM. So I know I have everything connected right, I just don't know why only the one object is showing up.
I know there are other posts similiar to this all over the internet, I just am having trouble figuring out my exact problem.
Question 2 - I get the error
"cannot read property insertRow of undefined"
in the console if I try to put the initial var row = table.insertRow(-1); inside my function, but I don't get the error if it's outside my function. I thought if it was inside the GenerateTable() then my function would be still be able to access it?
var table_data = [{
first_name: 'Zoe',
last_name: 'Heriot',
home: 'Space Station W3'
}, {
first_name: 'Jo',
last_name: 'Grant',
home: 'Earth'
}, {
first_name: 'Clara',
last_name: 'Oswald',
home: 'Earth'
}, {
first_name: 'Adric',
last_name: null,
home: 'Alzarius'
}, {
first_name: 'Susan',
last_name: 'Foreman',
home: 'Gallifrey'
}];
var row = table.insertRow(-1);
function GenerateTable() {
var table = document.getElementById('table')[1];
for (var i = 0; i <= table_data.length; i++) {
var firstName = table_data[i].first_name;
var lastName = table_data[i].last_name;
var home = table_data[i].home;
row.innerHTML = `
<td>${firstName}</td>
<td>${lastName}</td>
<td>${home}</td>
`;
};
};
if (document.attachEvent ? document.readyState === "complete" :
document.readyState !== "loading") {
GenerateTable();
} else {
document.addEventListener('DOMContentLoaded', GenerateTable);
}
<table id="table">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Home</th>
</tr>
</table>
A few things:
You can't access a variable before you define it. The first line of your script does this, which is why you get the error:
var row = table.insertRow(-1);
table isn't defined until inside the function, so you can't use it until you've told javascript what it is. Additionally you want to add a row for each trip through the loop, so you need to put the insertRow() call inside the loop where it will add a row each time.
Also, i the loop you want to stop when i < table_data.length not <= otherwise it will throw an error on the last trip through.
Here's a working snippet:
var table_data =[{ first_name : 'Zoe',
last_name : 'Heriot',
home : 'Space Station W3'},
{ first_name : 'Jo',
last_name : 'Grant',
home : 'Earth'},
{ first_name : 'Clara',
last_name : 'Oswald',
home : 'Earth'},
{ first_name : 'Adric',
last_name : null,
home : 'Alzarius'},
{ first_name : 'Susan',
last_name : 'Foreman',
home : 'Gallifrey'} ];
function GenerateTable(){
var table = document.getElementById('table');
for (var i=0; i < table_data.length; i++) {
var row = table.insertRow(-1);
var firstName = table_data[i].first_name;
var lastName = table_data[i].last_name;
var home = table_data[i].home;
row.innerHTML = `
<td>${firstName}</td>
<td>${lastName}</td>
<td>${home}</td>
`;
};
};
GenerateTable()
tr:nth-child(even) {
background: #ccdced;
}
td, th {
padding:.5em
}
<table id="table">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Home</th>
</tr>
</table>
Question 1:
row.innerHTML = `
<td>${firstName}</td>
<td>${lastName}</td>
<td>${home}</td>
`;
Is saying "remove everything in row.innerHTML and replace with <td>$.... And since the row value never change, you'll always write to the same row.
Question 2:
Have you tried to put table.insertRow() after the table var definition and remove the [1]? Like:
var table = document.getElementById('table');
var row = table.insertRow(-1);
You can read more about insertRow and how it can be used at Mozilla Developer pages.
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