<table style="width: 50%" id="myTable">
<tbody>
<tr><td>Row 1</td><td>dd</td><td>red</td><td>dd</td></tr>
<tr><td>Row 2</td><td>dd</td><td>green</td><td>dd</td></tr>
<tr><td>Row 3</td><td>dd</td><td>red</td><td>dd</td></tr>
</tbody>
</table>
Add Row
$(document).ready(function () {
$("a[name=addRow]").click(function() {
$("table#myTable tr:last").after('<tr><td>Row 4</td><td>dd</td><td>red</td><td>dd</td></tr>');
return false;
});
$('#myTable tbody tr td').each(function()
{
if ($(this).text() == 'red')
{
$(this).parent().css('background-color', 'red');
}
else if ($(this).text() == 'green')
{
$(this).parent().css('background-color', 'green');
}
});
});
why if i add new rows then this doesnt work? i try add live:
$('#myTable tbody tr td').live('each', function()
but this also doesnt work
LIVE: http://jsfiddle.net/pytP2/
This works:
$(document).ready(function () {
$("a[name=addRow]").click(function() {
$("table#myTable tr:last").after('<tr><td>Row 4</td><td>dd</td><td>red</td><td>dd</td></tr>');
initRow($("table#myTable tr:last"));
return false;
});
$('#myTable tbody tr').each(function()
{
initRow($(this));
});
function initRow(row)
{
row.find('td').each(function(){
var self = $(this);
var textInTD = $.trim(self.text());
if (textInTD == 'red')
{
row.css('background-color', 'red');
return false;
}
else if (textInTD == 'green')
{
row.css('background-color', 'green');
return false;
}
})
}
});
If you need, I can add comments to the code.
live will attach a handler to a specific event for all existing and future instances of the specified elements, which is different to what you're trying to do, as you need to update the styling of new elements added to the table. live would only be useful if you wanted to add say a 'click' event to each new row in your table.
To fix your code you need to call the style update function after each new element is added, there's a working demo here - http://jsfiddle.net/ipr101/zDvAQ/1/
live takes an event type (such as 'click') as a first parameter. See http://api.jquery.com/live/
This does not work because the onload code is only fired once: on load...
If you want the code to be executed after adding a new row, extract the wanted code into a new function and call it after adding the new rows
if you're worried about performance (if the table can get very big) you could also pass the new row to the function.
Related
I need to unbind datagrid row click event,
I have tried a lot using
$.each(gridData, function (index, row) {
if (row)
{
if (row["Islicense"].toString() == "false")
{
$('.grid_table tr').each(function () {
var ballyDataGridRow = $(this);
if (ballyDataGridRow.attr('valuemember') == row["ComponentID"]) {
// ballyDataGridRow.find("tr").unbind('click');
//ballyDataGridRow.find("tr").undelegate("click");
// ballyDataGridRow.find("tr").off("click");
//ballyDataGridRow.find('input').prop("disabled", true);
}
});
}
}
});
I have used unbind,undelegate,off, even its not working
If your ballyDataGridRow has had a click attached, then there is no need for the find('tr') as that is the tr already.
e.g. use this instead
ballyDataGridRow.off("click");
or
ballyDataGridRow.unbind("click");
At the moment you are searching for a tr within each tr, which is like doing this:
$('.grid_table tr tr')
Assume we have table:
<table>
<tr>first</tr>
<tr class="ClassName">second</tr>
<tr class="ClassName">third</tr>
</table
And We want to remove row with class='ClassName'
I wrote a code:
var Ids = $('.ClassName').map(function () {
return this
}).get();
if (Ids.length > 0) {
for (var i; i = 0; i++) {
Ids[i].hide();
}
}
I need to know if there are any rows with this class. If yes I need to remove them. If no I call ajax, read from db and add rows to table. Its part of Show/Hide mechanism
But my code do nothing. Rows still appear in the page. What should I change?
jQuery
// check if are any rows with this class
var $rows = $('table tr.ClassName');
if( $rows.length > 0 ) {
// remove them or hide with .hide();
$rows.remove();
} else {
// call ajax ...
}
Why not just:
$('table tr.ClassName').hide();
if you want remove permanent then you can use this one.
$('.ClassName').each(function(){
$(this).remove();
});
Here you go -
$("table tr[class='ClassName']").remove();
Please mark this as "Answered" if this solves your problem.
Try using hasClass() in jquery.
JQuery:
//Check if any row has class
if($('table tr').hasClass("ClassName")){ //remove from table }
else{
//do your ajax call here.
}
You can just remove all with that class and then check if there was any:
$(function () {
var $trs = $('table tr.ClassName');
$trs.remove();
if ($trs.length === 0) {
// Ajax-call
}
});
It should work
$("table").find(".ClassName").remove();
If you want to remove all the table rows other than first row means you can try this
$("table").find("tr:gt(0)").remove();
I have the following jquery to append to a table dynamically based on user interaction and data received from the server. Now each column in the table has some specific class and some style attributes like the column itemId is hidden and so on. My dynamic addition is working fine if I already have one row but if its none it just adds another header row which I can understand is because my code copies the last tr element. Question is how do I go about adding a row to 'tbody' when their are no rows.
function responseTopicAdded(data) {
$('#dialog-modal').dialog('close');
rowcopy = $('#datatable tr:last').clone();
rowcopy.children().each(function() {
switch($(this).attr('class')) {
case 'Name':
$(this).html(data.Name);
break;
case 'Description':
$(this).html(data.Description);
break;
case 'Icon':
$(this).html('<img src='+ data.Icon +'/>');
break;
case 'itemId':
$(this).html(data.itemId);
}
});
$('#datatable tr:last').after($(rowcopy));
}
My second question is that my table cells respond to a double click. But the newly added row never responds (even when there are previous rows and the row is added normally).
Why doesn't the listener work on the new row?
My listener goes like this:
$(document).ready(function() {
try {
$("td").dblclick(function() {
// ... my code goes here
}catch(a){
alert(a);
}
}
The reason the double click event doesn't work on newly added rows is because you are binding the click event before the elements exist. Try binding with this style (event delegation is the term):
$("#datatable").on("dblclick", "td", function() { //do stuff });
As per adding a tbody when one is not present, simply do a check to see if one exists:
if ($("#datatable tbody").length) { //it exists! } else { //it doesnt exist! }
You can go with template approach to create a template for your table row to be cloned when required.
Say your table is this:
<table id="datatable">
<thead>
<tr><th>Name</th>
<th>Description</th>
<th>icon</th>
<th>itemID</th></tr>
</thead>
<tbody></tbody>
</table>
When you populate:
//Create the template here// or keep it in HTML itself in a hidden div or something.
var template = $("<tr><td class='Name'></td><td class='Description'></td><td class='Icon'></td><td class='itemId'></td></tr>");
$(function () {
var newRow = $(template).clone(); //Clone the template
//just an initial load
newRow.find('.Name').text('AAA');
newRow.find('.Description').text('Some Description');
newRow.find('.Icon').text('Some Icon');
newRow.find('.itemId').text('1234');
//Initially clone
$('#datatable').find('tbody').append(newRow);
//register the handler using event delegation
$('#datatable tbody').on('click', 'tr', function () {
alert('clicked on ' + $(this).find('.Name').text());
});
$('#addNew').on('click', function () {
var rowcopy = $(template).clone(); //Clone the template
var data = {
Name: 'BBB',
Description: 'Some Description',
Icon: 'http://placehold.it/32x32',
itemId: '45676'
};
//Set the Css class name based on even odd row
rowcopy.addClass(function(){
return $('#datatable tbody tr').length % 2 == 0 ? "odd" : "even";
});
rowcopy.children().each(function () {
switch ($(this).attr('class')) {
case 'Name':
$(this).html(data.Name);
break;
case 'Description':
$(this).html(data.Description);
break;
case 'Icon':
$(this).html('<img src=' + data.Icon + '/>');
break;
case 'itemId':
$(this).html(data.itemId);
}
});
$('#datatable tbody').append($(rowcopy)); //Append it to the tbody.
});
});
Demo
For adding even/odd styles you can use css itself.
#datatable tbody tr:nth-child(odd) {
background-color:#cecece;
}
#datatable tbody tr:nth-child(even) {
background-color:yellow;
}
If not you want to do it with the class then:
rowcopy.addClass(function(){
return $('#datatable tbody tr').length % 2 == 0 ? "odd" : "even";
});
Demo
I am having four column in my table. When we click one of the first three td that will do one operation and when we click last td that will do other kind of operation.
I did like this
$('#items_list tr td').not('#items_list tr td:last-child').click(function() {
// Do something
}
$("#items_list tr td:last-child").click(function() {
// Do something
}
But those not working when Dom change. I try to use .live(), but the disadvantage of li is
Chaining methods is not supported. Any one can guide me?
There is no need to add events to every cell on the table. One event handler at the table tbody level can handle it.
jQuery("#foo tbody").on("click", function (evt) {
var elem = jQuery( evt.srcElement || evt.target );
if (elem.is("td:last-child")) {
alert("last child");
} else {
alert("not last child");
}
});
You might have to add code to the elem to look for the closest td if you have elements inside of the td.
if (!elem.is("td")) {
elem = elem.closest("td");
}
jsFiddle
$("#items_list tr td").last().click(function(){ });
I'm wondering if there is a more elegant means of modifying the parameter of an onclick event. I have a table that I am dynamically adding/removing elements from and I re-index the rows. Each row has a delete link that has the row's index (and a duplicate link) that needs to update its parameter to match the modified row id.
Currently my code looks like (simplified)
<a onclick="delRow(1)">delete</a>
and the javascript:
...
html = element.innerHTML;
html = html.replace(/dupRow(\\d+)/g, "dupRow(" + newIndex + ")");
html = html.replace(/delRow(\\d+)/g, "delRow(" + newIndex + ")");
element.innerHTML = html
and I would like it to become something along the lines of
if (element.onclick != null) {
element.onclick.params[0] = newIndex;
}
Any such way of accomplishing this? I also have jQuery if this helps.
Updates:
So thanks to the glorious help of #rich.okelly I have solved my issue
<script>
...
var newRow = '\
<tr>\
<td class="index" col="0">0</td>\
<td>this is content...</td>\
<td>Del</td>\
</tr>';
// re-index table indices in a non-efficient manner
function reIndexTable() {
$("#rpc-builder-table").find('.index').each(function (i) {
$(this).html(i)
})
}
// add row
function addRow() {
for (i = 0; i < $('#addRowCount').attr("value"); i++) {
$("#rpc-builder-table").append(newRow);
}
reIndexTable();
}
$(document).ready(function () {
// add row button
$('#addRowsButton').on('click', function () {
addRow();
});
// delete row
$('#rpc-builder-table').on('click', 'td a[row-delete="true"]', function () {
$(this).closest('tr').remove();
reIndexTable();
});
...
}
</script>
...
<div>
<label>Rows to add: </label>
<input id="addRowCount" value="1" size="2" />
<button id="addRowsButton">Add Row(s)</button>
</div>
<div><table id="rpc-builder-table"><tbody>
<tr>
<th>Idx </th>
<th>Some content (1)</td>
</tr>
</tbody></table></div>
...
I used the .on() function instead of the suggested .delegate() function since it is deprecated. Solution works well - hope it helps someone :)
If you change your html to something similar to:
<tr>
<td>
delete
</td>
</tr>
Then your javascript can be something like:
$('td a[data-delete="true"]').on('click', function() {
$(this).closest('tr').remove();
});
Update
If rows are added dynamically to a pre-exising table (table is interchangeable for any parent element), you can use the delegate method like so:
$('table').delegate('td a[data-delete="true"]', 'click', function() {
$(this).closest('tr').remove();
});
Instead of inline handlers, use event delegation to attach event handlers
$("#tableID").delegate("a", "click", delRow);
$("#tableID").on("click", "a", delRow); //jQuery 1.7
Inside the handler,
var row = $(this).closest("tr").index(); //Get the index of the parent row
Inline handlers get parsed into a function:
function onclick() {
delRow(1);
}
so changing them is difficult. Your example rewrites the entire row with the new parameter, which is bad practice.
The most brain dead solution is getting rid of the parameters and setting a variable isntead.
var row_to_dup = 42;
$("#a_row_dupper").bind('click', function (){
dupItem(row_to_dup);
});
//changing the row to dup
row_to_dup = 17;