How to update table cell value using jQuery - javascript

I am having problem updating table cell value using jQuery 1.4.2. it all works in Firefox and Safari but IE8 and IE9 is simply not doing anything. There is no warning, error or anything that would give me some hint where to look for it.
Table looks following:
<table id="test">
<tr id="1">
<td id="name">sample name</td>
<td id="schedule">sample value</td>
<td id="day">sample value</td>
</tr>
<tr id="2">
<td id="name">sample name</td>
<td id="schedule">sample value</td>
<td id="day">sample value</td>
</tr>
<tr id="3">
<td id="name">sample name</td>
<td id="schedule">sample value</td>
<td id="day">sample value</td>
</tr>
</table>
I am executing ajax call and getting json data:
{"Test": [
{"id":"1", "name":"John", "day":"Monday"},
{"id":"2", "name":"Marry", "day":"Thursday"}
]}
once data is received there is a loop which iterates through the json dataset and updates appropriate column with received data as following:
$.each(json.Tests, function(){
/* update test with details */
var test = this.hash;
/*set values for each test */
$("table#test tr[id=" + test + "]").find("#name").html(this.name);
$("table#test tr[id=" + test + "]").find("#schedule").html(this.status);
$("table#test tr[id=" + test + "]").find("#day").html(this.changed);
});
As I mentioned, this has been tested in Safari and Firefox all works fine but IE8 and IE9 seems not to do anything.

I think the id attribute should be reserved for unique identifiers in my opinion. How about changing the id attribute of the td elements to a class attribute or even name attribute. I suspect that IE is getting confused.
Also, if you keep ids unique and change the id attribute of the td to a class then you can change your code to something like:
$("#" + test + " td.name").html(this.name);
And because a number could represent pretty much anything also prefixing those ids with some sort of identifier prefix would be good. Something like:
$("#thing-" + test + " td.name").html(this.name);
And the html would look like this:
<table id="test">
<tr id="thing-1">
<td class="name">sample name</td>
<td class="schedule">sample value</td>
<td class="day">sample value</td>
</tr>
<tr id="thing-2">
<td class="name">sample name</td>
<td class="schedule">sample value</td>
<td class="day">sample value</td>
</tr>
<tr id="thing-3">
<td class="name">sample name</td>
<td class="schedule">sample value</td>
<td class="day">sample value</td>
</tr>
</table>
Hope that helps!

Ids aren't supposed to start with a number. Perhaps IE9 isn't as forgiving as the other browsers.

Have you an URL for us to Test your Script?

Related

How to loop a table in jQuery

I want to throw the last 2 digits of the clock, I use jquery but it always fails in looping
Only one row changes, i want to change all rows.
this is my code
$(document).ready(function(){
var jam = $("#jamberangkat").text();
var datearray = jam.split(":");
var newjam = datearray[0] + ":" + datearray[1];
return $("#jamberangkat").text(newjam);
});
<table>
<tbody>
<tr>
<td id="jamberangkat" style="width:20%;">{{ $data->jam }}</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
this is my result
It seems like you want to iterate through all the <td> with the ID of jamberangkat. Remember that IDs must be unique throughout the DOM, so you will need to use a class to identify that cell that you want to change.
Most jQuery methods are actually implicit iterators, so you can simply use a callback in $('.jamberangkat').text(<callback>) to perform the text filtering for you for all elements that matches the selector. What you want in that filter is:
Extract the text value of the element. This is accessible as the second argument in the .text() method: refer to the jQuery API documentation for .text()
Split the text by : as you have intended
Keep only the first two elements (in your code I deduced you only want to keep the first and second fragment of the array). This can be done by using .slice(0, 2)
Rejoin the spliced array (which now retains only the first two elements) using .join(':').
See proof-of-concept example below:
$(document).ready(function(){
$(".jamberangkat").text(function(index, txt) {
return txt.split(':').slice(0,2).join(':');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td class="jamberangkat" style="width:20%;">12:34:56</td>
<td>Random text</td>
</tr>
<tr>
<td class="jamberangkat" style="width:20%;">12:34:56</td>
<td>Random text</td>
</tr>
<tr>
<td class="jamberangkat" style="width:20%;">12:34:56</td>
<td>Random text</td>
</tr>
<tr>
<td class="jamberangkat" style="width:20%;">12:34:56</td>
<td>Random text</td>
</tr>
</tbody>
</table>

How can I implement dynamic rowspan

The code below is my latest attempt. There have been many others:
Javascript:
...
var issueArray = [];
_.each(issueGroups, function(i) {
var x = {
issue: i[0].issue,
comment: i[0].comment,
count: i.length,
new_row: 1
};
issueArray.push(x);
});
issueArray[0].new_row = 0;
var x = {
test: t[0].test,
issues: issueArray,
rowspan: issueArray.length
};
finalResult.push(x);
});
return finalResult;
The important thing to note here is that for each element of finalResult there is an array called issues that has a member called new_row which is true for all but the first row.
Template:
...
<tbody>
{{#each failuresByTest}}
<tr>
<td rowspan="{{rowspan}}">{{test}}</td>
{{#each issues}}
{{#if new_row}}
</tr>
<tr>
<td>{{issue}}</td>
<td>{{comment}}</td>
<td>{{count}}</td>
{{else}}
<td>{{issue}}</td>
<td>{{comment}}</td>
<td>{{count}}</td>
{{/if}}
{{/each}}
</tr>
{{/each}}
</tbody>
...
My data is such that the first element of finalResult has 3 issues. I expect it to look like this:
<tr>
<td rowspan="3">Test1</td>
<td>123</td>
<td>Bug 1</td>
<td>2</td>
</tr>
<tr>
<td>456</td>
<td>Bug 2</td>
<td>21</td>
</tr>
<tr>
<td>654</td>
<td>Bug 4</td>
<td>3</td>
</tr>
But it ends up looking like this:
<tr>
<td rowspan="3">Test1</td>
<td>123</td>
<td>Bug 1</td>
<td>2</td>
<td>
<table>
<tr>
<td>456</td>
<td>Bug 2</td>
<td>21</td>
</tr>
<tr>
<td>654</td>
<td>Bug 4</td>
<td>3</td>
</tr>
</table>
</td>
</tr>
However Meteor doesn't like this. I get:
=> Errors prevented startup:
While processing files with templating-compiler (for target web.browser):
client/templates/runs/run_page.html:128: Unexpected HTML close tag
</tr> <tr> <td><a h...
This side-tracked me so badly that I ended up putting the row tags wrongly to fix this and then it displayed wrongly. I have now edited the question accordingly since this is my real problem.
How do I solve this and persuade Meteor that actually I do know better than it!
Your template logic is flawed:
You are trying to insert a new <tr> inside a <td>. Since <tr> can only be contained inside tables, the browser will automatically add a table around it so that the html is valid.
<tbody>
{{#each failuresByTest}}
<tr>
<td rowspan="{{rowspan}}">{{test}}</td>
{{#each issues}}
{{#if new_row}}
<tr>
<td>
So depending on how each failureBytest should be rendered, you should either create a new table for each failure, or create a new row outside the previous row inseatd of inside it's cells.
I worked around Meteor's controlling behaviour with the following.
Javascript:
var issueArray = [];
_.each(issueGroups, function(i) {
var x = {
issue: i[0].issue,
comment: i[0].comment,
count: i.length,
new_row: 0
};
issueArray.push(x);
});
issueArray[0].new_row = 1;
_.extend(issueArray[0], {rowspan: issueArray.length});
_.extend(issueArray[0], {test: t[0].test});
var x = {
issues: issueArray
};
finalResult.push(x);
Note that the test name and rowspan have now moved into the first array element. I can probably remove new_row.
Template:
<tbody>
{{#each failuresByTest}}
{{#each issues}}
<tr>
{{#if new_row}}
<td rowspan="{{rowspan}}">{{test}}</td>
{{/if}}
<td>{{issue}}</td>
<td>{{comment}}</td>
<td>{{count}}</td>
</tr>
{{/each}}
{{/each}}
</tbody>
I really do not like putting "parent data" in the first array element. I prefer for all elements to be of exactly the same type/structure without duplicate/extra information added.

How do I change the text of a specific table cell based on class name and sibling?

I want to use jQuery to rename some text based on class and text within a sibling's tag. For example I'm trying to rename Sally to Samantha in the HTML below, based on the text within the sibling .field1 td (which is 421).
<table>
<tbody>
<tr class="adv-grid-row">
<td class="adv-grid-cell description">Sally</td>
<td class="adv-grid-cell units">Jibber</td>
<td class="adv-grid-cell field8">Jabber</td>
<td class="adv-grid-cell field1">421</td>
<td class="adv-grid-cell part_number">433</td>
<td class="adv-grid-cell field25">John</td>
</tr>
<tr class="adv-grid-row">
<td class="adv-grid-cell description">Test</td>
<td class="adv-grid-cell units">Each</td>
<td class="adv-grid-cell field8">Part</td>
<td class="adv-grid-cell field1">450</td>
<td class="adv-grid-cell part_number">431</td>
<td class="adv-grid-cell field25">Joe</td>
</tr>
</tbody>
</table>
This is what I have so far but it doesn't work:
$(".adv-grid-cell.field1 td:contains('421')").siblings(".adv-grid-cell.description").text('Samantha');
If that's not possible, how do I just look for "Sally" using the td's class and rename it to "Samantha"?
Thanks in advance.
Your selector is incorrect; the .field1 is the td which contains the text. Try this:
$(".adv-grid-cell.field1:contains('421')").siblings(".adv-grid-cell.description").text('Samantha');
Working example
It's worth noting that the :contains selector matches on the provided string being anywhere in the innerText of the DOMElement, so it would match 421, a421z and not 421. If you need to match on 421 only, you would need to use filter():
$('.adv-grid-cell.field1').filter(function() {
return $(this).text().trim() == '421';
}).siblings(".adv-grid-cell.description").text('Samantha');

Show rows in table with cells name attribute containing string from input (JQuery)

I would like to have keyup function that would show only rows matching the input text by cell that spans on multiple rows.
Consider following table:
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1'> dummy1 </td>
</tr>
<tr>
<td name='Key1'> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2'> dummy3 </td>
</tr>
<tr>
<td name='Key2'> dummy4 </td>
</tr>
</table>
jsfiddle
Here each row has second td tag with name that matches its "parent" column text. So when I type 'Key1' at the input field I would like it to show only dummy1 and dummy2. Is it possible in jquery?
I understand that you want to display the rows that has a matching name. If this is wrong, please elaborate more, then I can update it.
Here is a demo: https://jsfiddle.net/erkaner/gugy7r1o/33/
$('input').keyup(function(){
$('tr').hide();
$("td").filter(function() {
return $(this).text().toLowerCase().indexOf(keyword) != -1; }).parent().show().next().show();
});
});
Here's my take on your issue, assuming you always want the first column to show. https://jsfiddle.net/gugy7r1o/2/
<input type="text" id="myInput" />
<table border='1'>
<tr>
<td rowspan='2'>Key1</td>
<td name='Key1' class="data"> dummy1 </td>
</tr>
<tr>
<td name='Key1' class="data"> dummy2 </td>
</tr>
<tr>
<td rowspan='2'>Key2</td>
<td name='Key2' class="data"> dummy3 </td>
</tr>
<tr>
<td name='Key2' class="data"> dummy4 </td>
</tr>
</table>
.data{
display:none;
}
var theData = $('td.data');
var input = $('#myInput').on('keyup', function(){
theData.hide();
var value = input.val();
var matches = theData.filter('[name="'+value+'"]');
matches.show();
});
Firstly, I would recommend using <ul> to wrap each key in as tables should be used for data structure (Forgive me if that is what it is being used for).
Secondly, just attach an on keyup event to the search box and then find matches based on the id. See example below:
JS Fiddle Demo
It is also worth mentioning that it could be useful attaching a timeout to the keyup event if you end up having large amounts of rows so that only one filter is fired for fast typers!

jQuery - Select current table row values

When someone clicks on the Download button in my table, I want to pass the date values from that particular row to a function. Currently I can only pass the date values from the first table row.
This is the selector I'm using:
$(this).parent().find('#period-start');
Which always returns:
[<td id=​"period-start">​5/1/2013​</td>]
I've tried combinations of the parent, child, find and closest selectors, but haven't been able to stumble across the correct one to grab the date values from the current row. Thanks.
Table
<table id="tblStatements" class="table">
<thead>
<tr>
<th>Period Starting</th>
<th>Period Ending</th>
<th>Download</th>
</tr>
</thead>
<tbody>
<tr>
<td id='period-start'>5/1/2013</td>
<td id='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>4/1/2013</td>
<td id='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td id='period-start'>3/1/2013</td>
<td id='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
</tbody>
</table>
ID's are always supposed to be unique in HTML. So, you might try out this, w/o using an ID:
// Get the first td
var periodStart = $(this).closest('tr').children('td:eq(0)').text();
// Get the second td
var periodEnd = $(this).closest('tr').children('td:eq(1)').text();
FIDDLE DEMO
Use this - don't use duplicate ID's though, use class instead
$(this).closest('tr').find('#period-start');
or -
$(this).closest('td').siblings('#period-start');
try this
$(this).parent().siblings('#period-start');
Make sure all your ids is unique..your HTML is invalid.... change it to class and try this
$(this).parent().siblings('.period-start');
You should not use more then one element with the same id use class insidead.
<tr>
<td class='period-start'>5/1/2013</td>
<td class='period-end'>5/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>4/1/2013</td>
<td class='period-end'>4/30/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
<tr>
<td class='period-start'>3/1/2013</td>
<td class='period-end'>3/31/2013</td>
<td><button type='submit'>Download</button></td>
</tr>
and use this code to select proper element
$(this).parents('tr').find('.period-start');
try this
$.trim($(this).closest('tr').find('[id="period-start"]').html());//this gives start date

Categories

Resources