I've got a table with 5 rows and two columns. Each row, has an ID column, ranging from 1-5.
I want to add JSON data to that said table, IF, that data has a matching ID to that row. If NO data matches that rows ID, add "No Matching Record" to that rows second column.
HTML Table
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td></td>
</tr>
</tbody>
</table>
Json Data
{"data":[
{"id":"1", "lastName":"Doe"},
{"id":"3", "lastName":"Jones"}
]}
Expected Result
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Doe</td>
</tr>
<tr>
<td>2</td>
<td>No Matching Record</td>
</tr>
<tr>
<td>3</td>
<td>Jones</td>
</tr>
<tr>
<td>4</td>
<td>No Matching Record</td>
</tr>
<tr>
<td>5</td>
<td>No Matching Record</td>
</tr>
</tbody>
</table>
You can do this with .each() to loop each tr and then use find() to get object from data that has same id as text in td.
//Loop each row or tr
$('tbody tr').each(function() {
//Get text or number from each first td in every row
var i = $(this).find('td:first').text();
//Find object from data with this id or current id of td
var r = data.data.find((e) => e.id == i);
//Select second td from current row
var t = $(this).find('td:eq(1)');
//If Object is found with current id add lastName as text else add dummy text or No Matching Record
(r != undefined) ? t.text(r.lastName): t.text('No Matching Record');
});
var data = {"data":[{"id":"1", "lastName":"Doe"},{"id":"3", "lastName":"Jones"}]}
$('tbody tr').each(function() {
var i = $(this).find('td:first').text();
var r = data.data.find((e) => e.id == i);
var t = $(this).find('td:eq(1)');
(r != undefined) ? t.text(r.lastName): t.text('No Matching Record');
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td></td>
</tr>
</tbody>
</table>
If you want to filter by index of rows instead of text from td you can just use $(this).index() + 1; and the rest is same
var data = {
"data": [{
"id": "1",
"lastName": "Doe"
}, {
"id": "3",
"lastName": "Jones"
}, ]
}
//Loop each row or tr
$('tbody tr').each(function() {
//Get index of row
var i = $(this).index() + 1;
//Find object from data with this id or current id of td
var r = data.data.find((e) => e.id == i);
//Select second td from current row
var t = $(this).find('td:eq(1)');
//If Object is found with current id add lastName as text else add dummy text or No Matching Record
(r != undefined) ? t.text(r.lastName): t.text('No Matching Record');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td></td>
</tr>
</tbody>
</table>
First, add classes to the two types of td's for convenience. Then following code should work. Here I am iterating through all rows in tbody and then searching through the json if any matching value is found. If no matching value is found, default value ("No data found") is put in the lastName column.
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td class="id">1</td>
<td class="name"></td>
</tr>
<tr>
<td class="id">2</td>
<td class="name"></td>
</tr>
<tr>
<td class="id">3</td>
<td class="name"></td>
</tr>
<tr>
<td class="id">4</td>
<td class="name"></td>
</tr>
<tr>
<td class="id">5</td>
<td class="name"></td>
</tr>
</tbody>
</table>
var json = {"data":[
{"id":"1", "lastName":"Doe"},
{"id":"3", "lastName":"Jones"}
]};
$(".table tbody tr").each(function(index){
var curId = $(this).find(".id").text();
var nameField = "No data found";
for( var i = 0; i < json.data.length; i++ )
{
var row = json.data[i];
if( row.id == curId )
{
nameField = row.lastName;
return false;
}
}
$(this).find(".name").text( nameField );
});//each
The following code would do the trick:
var response = {"data":[
{"id":"1", "lastName":"Doe"},
{"id":"3", "lastName":"Jones"}
]};
var myData = response.data;
var rows = $('#myDataTable tbody tr');
var cells, index, itemFound = false;
rows.each(function (index) {
cells = $(this).find('td');
itemFound = false
for (index=myData.length-1 ; index>= 0 && !itemFound; index--) {
if (cells.eq(0).text() == myData[index].id) {
itemFound = true;
cells.eq(1).text(myData[index].lastName);
myData.splice(index, 1);
}
}
if (!itemFound) {
cells.eq(1).text('No matching record');
}
});
See my working js fiddle:
https://jsfiddle.net/gkptnnxe/
If you don't want to add class or id's to your td's then you can use this.
var obj = {"data":[
{"id":"1", "lastName":"Doe"},
{"id":"3", "lastName":"Jones"}
]};
var trs = document.getElementsByTagName("tr");
// don't need for i==0
for(var i=1; i<trs.length; i++){
var tds = trs[i].children;
var id = tds[0].innerHTML;
var nameFound = false;
//search this id in json.
var len = obj.data.length;
for(var j=0; j<obj.data.length; j++){
if(obj.data[j].id == id){
// If found then change the value of this lastName cell.
tds[1].innerHTML = obj.data[j].lastName;
nameFound = true;
}
}
// If id is not found is json then set the default message.
if(nameFound == false){
tds[1].innerHTML = "No mathcing records";
}
}
<table class="table table-striped">
<thead>
<tr>
<th>ID</th>
<th>Lastname</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td></td>
</tr>
<tr>
<td>2</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td></td>
</tr>
<tr>
<td>4</td>
<td></td>
</tr>
<tr>
<td>5</td>
<td></td>
</tr>
</tbody>
</table>
You can get td by index and check the text of td if it matches add name to next td
var data = {
"data": [
{ "id": "1", "lastName": "Doe" },
{ "id": "3", "lastName": "Jones" }
]
};
$(".table-striped tbody tr").each(function(){
var index = data.data.map(function (e) { return e.id }).indexOf($(this).first().text().trim());
if(index > -1)
$(this).children('td:eq(1)').text(data.data[index].lastName);
else
$(this).children('td:eq(1)').text('No matching record');
});
Related
I have many tables and I want to give all tr's individual ids. I loop through all tbody but it only affects first tbody, not all of them. When I add loop indicating each tbody they work. Is there any efficient way available to loop through all tbody and give the tr's individual id. I want to do it using vanilla javascript, no jQuery.
My sample code here :
<table><tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody></table>
<table><tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody></table>
Javascript :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[i].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
}
Second Try :
var c = document.getElementsByTagName('tbody');
var _trIndex = 1;
for ( i=0; i<c.length; i++) {
var x = c[0].rows;
for (i=0; i<x.length; i++){
x[i].setAttribute('id','tr'+_trIndex++)
}
var y = c[1].rows;
for (i=0; i<y.length; i++){
y[i].setAttribute('id','tr'+_trIndex++)
}
}
Probably this is what you need:
// Instead of getting the table bodies, I get only the table
// rows inside the tbody elements.
var c = document.querySelectorAll('tbody tr');
// Here I check if definitely the above query found any values.
if ( c ) {
// Then I do the itteration to the found tr elements
for ( i = 0; i < c.length; i++) {
// And here I set the ID the same way you did in your example
c[i].setAttribute('id','tr'+i);
}
}
<table>
<tbody>
<tr><td>No.</td><td>Name</td><td>Score</td></tr>
<tr><td>01</td><td>ted</td><td>0.50</td></tr>
<tr><td>02</td><td>joe</td><td>0.25</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Address</td><td>Phone</td></tr>
<tr><td>joe</td><td>LA</td><td>012345</td></tr>
<tr><td>ted</td><td>NY</td><td>0124</td></tr>
</tbody>
</table>
<table>
<tbody>
<tr><td>Name</td><td>Spec</td><td>Budget</td></tr>
<tr><td>joe</td><td>i5</td><td>458</td></tr>
<tr><td>ted</td><td>i7</td><td>768</td></tr>
</tbody>
</table>
You can achieve this with a single line of javascript.
document.querySelectorAll("tbody tr").forEach((element, index) => element.setAttribute("id", "tr" + index));
<table>
<thead>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
</thead>
<tbody>
<tr>
<td>No.</td>
<td>Name</td>
<td>Score</td>
</tr>
<tr>
<td>01</td>
<td>ted</td>
<td>0.50</td>
</tr>
<tr>
<td>02</td>
<td>joe</td>
<td>0.25</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Address</td>
<td>Phone</td>
</tr>
<tr>
<td>joe</td>
<td>LA</td>
<td>012345</td>
</tr>
<tr>
<td>ted</td>
<td>NY</td>
<td>0124</td>
</tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<td>Name</td>
<td>Spec</td>
<td>Budget</td>
</tr>
<tr>
<td>joe</td>
<td>i5</td>
<td>458</td>
</tr>
<tr>
<td>ted</td>
<td>i7</td>
<td>768</td>
</tr>
</tbody>
</table>
Problem
I have a table with one or more empty rows. How to hide empty rows from the table?
For example
1 - John | Alfredo
2 - Mark | Zuck
3 - |
4 - Carl | Johnson
In this case, I'd like to delete the third row.
Step Tried
I found how to delete a specific row, what about deleting all the empty rows?
deleteEmptyRows();
function deleteEmptyRows() {
var myTable = document.getElementById("myTable")
var rowToDelete = 2;
myTable.deleteRow(rowToDelete)
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
</tbody>
</table>
This is how you can dynamically hide empty table rows with javascript.
deleteEmptyRows();
function checkIfCellsAreEmpty(row) {
var cells = row.cells;
var isCellEmpty = false;
for(var j = 0; j < cells.length; j++) {
if(cells[j].innerHTML !== '') {
return isCellEmpty;
}
}
return !isCellEmpty;
}
function deleteEmptyRows() {
var myTable = document.getElementById("myTable");
for(var i = 0; i < myTable.rows.length; i++) {
var isRowEmpty = checkIfCellsAreEmpty(myTable.rows[i]);
if (isRowEmpty) {
myTable.rows[i].style.display = "none";
}
}
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
</tbody>
</table>
Here, a simple method for row is empty (this allows us to check for other conditions easily later).
Loop over rows and call remove if empty.
const rowIsEmpty = (tr) => Array.from(tr.querySelectorAll('td')).every(td => td.innerText === "");
deleteEmptyRows();
function deleteEmptyRows() {
var myTable = document.getElementById("myTable");
myTable.querySelectorAll('tr').forEach(tr => {
if(rowIsEmpty(tr)) tr.remove();
});
}
<table border="1" cellspacing="1" cellpadding="1" id ="myTable">
<tbody>
<tr>
<td>John</td>
<td>Alfredo</td>
</tr>
<tr>
<td>Mark</td>
<td>Zuck</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td>Carl</td>
<td>Johnson</td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Was answered in another thread.
Jquery: hiding empty table rows
Loops through all table tr rows, and checks td lengths. If the td length is empty will hide.
$("table tr").each(function() {
let cell = $.trim($(this).find('td').text());
if (cell.length == 0){
console.log('Empty cell');
$(this).addClass('nodisplay');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>1</td>
</tr>
<tr>
<!-- Will hide --> <td></td>
</tr>
</table>
With native Javascript:
function removeRow(src) {
var tableRows = document.getElementById(src).querySelectorAll('tr');
tableRows.forEach(function(row){
if((/^\s*$/).test(row.innerText)){
row.parentNode.removeChild(row);
}
});
}
removeRow('myTable');
The only problem is when you have some other characters in the row, except the whitespaces. This regex checks for blank characters, but if u have a dot inside or any other non empty character, it will fail.
I started on that http://jsfiddle.net/DRFBG/
And if I add tables so mytable1, mytable2,...
<table id="mytable1" border="1">
<tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4</th></tr>
<tr class="data"><td>1st</td><td>1.1</td><td></td><td>1</td></tr>
<tr class="data"><td>2nd</td><td>2.01</td><td></td><td>2</td></tr>
<tr class="data"><td>3rd</td><td>3.001</td><td></td><td>3</td></tr>
<tr class="data"><td>4th</td><td>4.01</td><td></td><td>4</td></tr>
</table>
<table id="mytable2" border="1">
<tr><th>Column1</th><th>Column2</th><th>Column3</th><th>Column4</th></tr>
<tr class="data"><td>1st</td><td>1.1</td><td>1</td><td></td></tr>
<tr class="data"><td>2nd</td><td>2.01</td><td>2</td><td></td></tr>
<tr class="data"><td>3rd</td><td>3.001</td><td>3</td><td></td></tr>
<tr class="data"><td>4th</td><td>4.01</td><td>4</td><td></td></tr>
</table>
How could I uniform my javascript code for all tables?
I've already tried passing by table[div^=mytable]*, but the problem is the second selector in the function.
So any ideas please? Thank you? Sorry for my english
By the way, the code is to remove th with empty td for each table
$('#mytable2 th').each(function(i) {
var remove = 0;
var tds = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')')
tds.each(function(j) { if (this.innerHTML == '') remove++; });
if (remove == ($('#mytable2 tr').length - 1)) {
$(this).hide();
tds.hide();
}
});
One approach is, selecting tables first and get their id and after that, doing the approach of http://jsfiddle.net/DRFBG/ on each of them like the following:
$('table').each(function()
{
var tb_id = $(this).attr('id');
$('#'+tb_id+' th').each(function(i) {
var remove = 0;
var tds = $(this).parents('table').find('tr td:nth-child(' + (i + 1) + ')')
tds.each(function(j) { if (this.innerHTML == '') remove++; });
if (remove == ($('#'+tb_id+' tr').length - 1)) {
$(this).hide();
tds.hide();
}
});
});
Here is the working jsfiddle
To select all on your page you can use "table" selector.
So you'd need to use $('table2 th') instead of $('#mytable2 th')
One possible solution would be to loop through each column of each table, then check if there are any non-empty cells. If there is not, then you can safely remove() all the td and th within that column.
Note that the removal needs to be done last, otherwise it will affect the indexing of the following columns. You can do that by simply marking the cells to be removed with a class, and then selecting that class once all loops complete. Try this:
$('table').each(function() {
var $table = $(this);
var rows = $table.find('tr').length - 1; // -1 to account for the headings
$table.find('th').each(function(i, th) {
var $empty = $table.find(`td:nth-child(${i + 1}):empty`);
if ($empty.length == rows)
$empty.add(this).addClass('to-remove');
})
$table.find('.to-remove').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="mytable1" border="1">
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
<th>Column4</th>
</tr>
<tr class="data">
<td>1st</td>
<td>1.1</td>
<td></td>
<td>1</td>
</tr>
<tr class="data">
<td>2nd</td>
<td>2.01</td>
<td></td>
<td>2</td>
</tr>
<tr class="data">
<td>3rd</td>
<td>3.001</td>
<td></td>
<td>3</td>
</tr>
<tr class="data">
<td>4th</td>
<td>4.01</td>
<td></td>
<td>4</td>
</tr>
</table>
<table id="mytable2" border="1">
<tr>
<th>Column1</th>
<th>Column2</th>
<th>Column3</th>
<th>Column4</th>
</tr>
<tr class="data">
<td>1st</td>
<td>1.1</td>
<td>1</td>
<td></td>
</tr>
<tr class="data">
<td>2nd</td>
<td>2.01</td>
<td>2</td>
<td></td>
</tr>
<tr class="data">
<td>3rd</td>
<td>3.001</td>
<td>3</td>
<td></td>
</tr>
<tr class="data">
<td>4th</td>
<td>4.01</td>
<td>4</td>
<td></td>
</tr>
</table>
This code works but checks only the first column. I want to check the 2nd column instead with the points. How do I alter it?
HTML Table:
<table width="100%">
<thead>
<tr>
<th width="60%">Name</th>
<th width="20%">School</th>
<th width="20%">Points</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="4"><h1>Event 1</h1></td>
<td>School1</td>
<td>74</td>
</tr>
<tr>
<td>School2</td>
<td>69</td>
</tr>
<tr>
<td>School3</td>
<td>71</td>
</tr>
<tr>
<td>School4</td>
<td>11</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td rowspan="4"><h1>Event 2</h1></td>
<td>School1</td>
<td>34</td>
</tr>
<tr>
<td>School5</td>
<td>29</td>
</tr>
<tr>
<td>School3</td>
<td>62</td>
</tr>
<tr>
<td>School7</td>
<td>15</td>
</tr>
</tbody>
</table>
jQuery:
var $tbody = $('#caltbl tbody');
$tbody.find('tr').sort(function (a, b) {
var tda = $(a).find('td:eq(0)').text();
var tdb = $(b).find('td:eq(0)').text();
// if a < b return 1
return tda > tdb ? 1
// else if a > b return -1
: tda < tdb ? -1
// else they are equal - return 0
: 0;
}).appendTo($tbody);
How do I got about this?
JSFIDDLE
EDIT: I'm sorry guys but my live code is different with rowspan being used. Is there a possibility to have this in ascending order so that the events are sorted differently?
eq(0) means you are using the first index. Change it to eq(1) so that it can consider the second index.
var tda = $(a).find('td:eq(1)').text();
var tdb = $(b).find('td:eq(1)').text();
You can sort the trs. Detach the td and insert to an array. Then append them back to each row
Add some class to simplify coding.
JSFIDDLE
HTML
<table width="100%">
<thead>
<tr>
<th width="60%">Name</th>
<th width="20%">School</th>
<th width="20%">Points</th>
</tr>
</thead>
<tbody>
<tr class="event1">
<td rowspan="4"><h1>Event 1</h1></td>
<td>School1</td>
<td class="point">74</td>
</tr>
<tr class="event1">
<td>School2</td>
<td class="point">69</td>
</tr>
<tr class="event1">
<td>School3</td>
<td class="point">71</td>
</tr>
<tr class="event1">
<td>School4</td>
<td class="point">11</td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
<tr>
<td rowspan="4"><h1>Event 2</h1></td>
<td>School1</td>
<td>34</td>
</tr>
<tr>
<td>School5</td>
<td>29</td>
</tr>
<tr>
<td>School3</td>
<td>62</td>
</tr>
<tr>
<td>School7</td>
<td>15</td>
</tr>
</tbody>
</table>
JavaScript
var $tbody = $(' tbody');
var array = [];
$tbody.find('.event1').sort(function (a, b) {
var tda = $(a).find('.point').text();
var tdb = $(b).find('.point').text();
return tda - tdb;
}).each(function (idx, tr) {
array.push($(tr).children('td').not('[rowspan]').detach());
});
$.each(array, function (idx, obj) {
$(obj).appendTo($('.event1:eq(' + idx + ')'));
});
The JavaScript only applies to event1. You can simply modify it for arbitrary events.
Change the index as Mayank Pandey said. And..
Since your second column is number, you can just return their difference.
var $tbody = $('#caltbl tbody');
$tbody.find('tr').sort(function (a, b) {
var tda = parseInt($(a).find('td:eq(1)').text(), 10); // always use the base number
var tdb = parseInt($(b).find('td:eq(1)').text(), 10);
return tda - tdb;
}).appendTo($tbody);
Please take a look at this FIDDLE. How would you make sure it only matches the occurrence of Sodium that appear at the beginning of the line in a table cell, for example :
<td>Sodium</td>, <td>Sodium (from Kitchen Salt)</td>
but not
<td>Vitamin sodium</td>,<td>Fish Sodium</td>
My attempt
`var find_Sodium = /^Sodium/
alert($('.'+title+'table').find('td:contains(find_Sodium)').next().html());`
isn't working.
$.ajax({
url: "url.json",
success: function (data) {
$(data.query.results.json.json).each(function (index, item) {
var title = item.title;
var table = item.table;
if (table.indexOf("Sodium") >= 0) {
$('.'+ title+'table').html(''+table+'');
var find_Sodium = /^Sodium/;
alert($('.'+title+'table').find('td:contains(find_Sodium)').next().html());
}
});
},
error: function () {}
});
Table Structure:
<table class="tablesorter">
<thead>
<tr>
<td>Ingredient</td>
<td>Amount</td>
<td>% Daily Value**</td>
</tr>
</thead>
<tbody>
<tr>
<td>Calories</td>
<td>10</td>
<td></td>
</tr>
<tr>
<td>Sodium</td>
<td>2g</td>
<td><1</td>
</tr>
<tr>
<td>Vitamin C</td>
<td>110mg</td>
<td>4</td>
</tr>
<tr>
<td>Potassium sodium</td>
<td>235mg</td>
<td>6</td>
</tr>
<tr>
<td>Omega 6</td>
<td>1100mg</td>
<td>*</td>
</tr>
<tr>
<td>Vitamin Sodium</td>
<td>1200mg</td>
<td>*</td>
</tr>
<tr>
<td>Vitamin E</td>
<td>300mg</td>
<td>*</td>
</tr>
</tbody>
</table>
:contains does not accept a regex, the way to do this is to filter()
$('.'+title+'table').find('td').filter(function() {
return $(this).text().indexOf('Sodium') === 0;
}).next().html();
FIDDLE
using indexOf === 0 makes sure Sodium has an index of zero, being the first thing to occur in the elements text