0
$('#action_button').click(function(){
    var tbody = $('#table_body').prepend(''+
        '<tr class="fresh">'+
            '<td>John Doe</td>'+
            '<td>235-75-75</td>'+
            '<td>some text</td>'+
            '<td>@#!@#!%!#%</td>'+
        '</tr>');

    setTimeout(function(){
        tbody.children('tr:first-child').removeClass('fresh');
    }, 1000);
});

I'm going to add a few rows with «fresh» class in the table. Then I want to remove the class of each new line after a certain time. But it does not work the way I planned. If you add multiple rows, the class will be removed only at the last added row. How to fix that?

jsfiddle

Thanks a lot :)

Fizzix
  • 23,679
  • 38
  • 110
  • 176
Aleksandr
  • 3
  • 3

3 Answers3

2

Create the element, then prepend it to the table, keeping a reference to the element to use later when removing the class. This will still let you remove the class one element at a time but it won't matter if additional elements are added before the previous ones are removed. Updated fiddle at http://jsfiddle.net/HmH3n/3/

$('#action_button').click(function(){
    var $tr = $('<tr class="fresh">'+
            '<td>John Doe</td>'+
            '<td>235-75-75</td>'+
            '<td>some text</td>'+
            '<td>@#!@#!%!#%</td>'+
        '</tr>');

    $('#table_body').prepend($tr);

    setTimeout(function(){
        $tr.removeClass('fresh');
    }, 1000);
});
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Thats exactly what I want! Thank you! – Aleksandr Jun 16 '14 at 04:48
  • @AlexFux you might also try `$tr.prependTo('#table_body').delay(1000).toggleClass('fresh');` – tvanfosson Jun 16 '14 at 04:50
  • I try to replace code after creating `$tr` element by `$tr.prependTo('#table_body').delay(1000).toggleClass('fresh');` but it doesn't work. [jsfiddle](http://jsfiddle.net/zzaebok/HmH3n/7/) – Aleksandr Jun 16 '14 at 05:24
  • @AlexFux - my bad, `toggleClass` doesn't use the effects queue. You'd need to do something like `$tr.css('background-color','#00ff00').prependTo('#table_body').delay(1000).animate('background-color','#ffffff');` – tvanfosson Jun 16 '14 at 12:45
  • you are right but we can't use `animate()` to change `background-color` property (via [this](http://stackoverflow.com/questions/16863640/jquery-animate-and-backgroundcolor)) and we also can't use `delay()` with `css()` (via [this](http://stackoverflow.com/questions/4283141/jquery-change-background-color)). My solution looks like this `$tr.css('background-color','#00ff00').prependTo('#table_body').delay(1000).queue(function(){$(this).css("background-color", "#fff");});` – Aleksandr Jun 17 '14 at 05:06
0

You are attempting to manipulate a variable that is not an object.

var tbody is completey different to var $tbody

Explaination here: What is the difference between "$variable" and "variable" - JavaScript - jQuery

Also, you should not start a prepend while at the same time saving it as a variable to table_body. The best practice is to do them separately. Also, not everything has to be placed within the click event. Save both of your objects outside of it so they are not being created over and over again.

var $tbody = $('#table_body');

$('#action_button').click(function () {
    var $tr = $('<tr class="fresh">' +
        '<td>John Doe</td>' +
        '<td>235-75-75</td>' +
        '<td>some text</td>' +
        '<td>@#!@#!%!#%</td>' +
        '</tr>');

    $tbody.prepend($tr);

    setTimeout(function () {
        $tr.removeClass('fresh');
    }, 1000);
});

As you can see above, we save the div with the ID of table_body as an object of $tbody so that we can use it over and over again without forcing the DOM to search for it over and over again since it saves it in memory. We also do the save with the new tr element for reuseability.

WORKING EXAMPLE HERE

Community
  • 1
  • 1
Fizzix
  • 23,679
  • 38
  • 110
  • 176
  • Uh what? Where do you see `$tbody`? And why are they different? – Felix Kling Jun 16 '14 at 04:48
  • Hey @FelixKling - Posted the question without adding everything, my bad. Check it now. – Fizzix Jun 16 '14 at 04:50
  • Whether you call the variable `tbody` or `$tbody` doesn't make a difference. And `.prepend()` returns the selected element, not the appended one. So `var tbody = $('tbody').prepend(...)` is perfectly fine. – Felix Kling Jun 16 '14 at 04:52
  • @FelixKling - It may be perfectly fine, but it is definitely not the best coding practice. Would be far more efficient to save the `tr` as an object to reuse it, same with the table body. Therefore, the click event is not recreating an object, just appending one that already exist in memory. – Fizzix Jun 16 '14 at 05:01
  • There is one nuance. If you try to add many rows at once, after one second pass, all the new lines will be white. It's hard to explain, just try to add new lines without stopping for a few seconds. – Aleksandr Jun 16 '14 at 05:03
  • @AlexFux - New find haha. All fixed :) – Fizzix Jun 16 '14 at 05:19
  • I totally agree with getting a reference to the element outside the handler, but your first statement, *"You are attempting to manipulate a variable that is not an object. `var tbody` is completey different to `var $tbody`"* is just wrong and irrelevant to the problem the OP is facing. – Felix Kling Jun 16 '14 at 05:20
  • @fizzix Thats awesome. But tvanfosson was the first. Can i accept multiple answers? I'm new in SO. – Aleksandr Jun 16 '14 at 05:29
  • @AlexFux - Unfortunately you cannot accept more than one answer. Although, when you earn enough reputation points, you can come back and upvote the answer if you like :) – Fizzix Jun 16 '14 at 05:41
0

You can add a temp class on row and then remove it.

$('#action_button').click(function(){
    var tbody = $('#table_body').prepend(''+
    '<tr class="fresh tmpClass">'+
        '<td>John Doe</td>'+
        '<td>235-75-75</td>'+
        '<td>some text</td>'+
        '<td>@#!@#!%!#%</td>'+
    '</tr>');


setTimeout(function(){
     $('#table_body').find('.tmpClass').removeClass('fresh').removeClass('tmpClass');
 }, 1000);
Vicky
  • 603
  • 5
  • 6