9

I'm using the following jQuery to pull new data and replace the contents of the DIV listdata

$(function(){
$('.refresh').click(function(event) {
    event.preventDefault();

    $.ajax({
        url: "_js/data.php",
        success: function(results){
            $('#listdata').replaceWith(results);
        }
    });
});
});

The script is triggered by numerous links on the page, such as:

<a href="" id="update1" class="refresh">Update 1</a>
<a href="" id="update2" class="refresh">Update 2</a>

For some reason the script only works on the first click of a link. Subsequent clicks do not refresh the data.

I've seen various fixes but nothing that I can get working. Any suggestions?

Paul
  • 661
  • 4
  • 12
  • 22

4 Answers4

31

It looks to me like your problem is with using replaceWith.

You're removing the element which matches $('#listdata') on the first call of replaceWith, so subsequent refreshes can't find where the data is supposed to be placed in the document.

You could try something like

 $('#listdata').empty();
 $('#listdata').append(results);

or chained like this

 $('#listdata').empty().append(results);
Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
Sam Dufel
  • 17,560
  • 3
  • 48
  • 51
  • I think you've hit the nail on the head, but this particular fix doesn't work – Paul Feb 14 '11 at 17:45
  • Sorry, I missed that you'd switched **replaceWith** for **append**. Perfect! – Paul Feb 14 '11 at 17:47
  • @EBM, you should open up a question about it then. If this solution doesn't work for you, then there's some difference in what you're doing. – Sam Dufel Nov 28 '12 at 20:02
  • This drove me nuts for ages and then I finally worked out what was going on. As per Sam Duel's reply the problem is that replaceWith is replacing the whole html so that particular id (or class) has been repalced hence why its not there to select a second time! My solution was to make sure the replacment HTML has the class I was selecting against to ensure I picked it up a second time – Trevor Aug 24 '16 at 16:37
3

If you're using replaceWith(), you're replacing #listdata with a brand new element altogether.

If data isn't something like <div id="listdata"></div> then #listdata is disappearing after the replaceWith(). I'm thinking you should probably use html() instead.

Dominic Barnes
  • 28,083
  • 8
  • 65
  • 90
0

Try:

$('a.refresh').live('click', function(e) {
    e.preventDefault();

    $.ajax({
        url: '_js/data.php',
        success: function(data) {
            $('#listdata').empty().html(data);
        }
    });
});

If the .refresh anchors are inside the #listdata element, then delegation is a more optimized solution:

var list = $('#listdata');

list.delegate('a.refresh', 'click', function(e) {
    e.preventDefault();

    $.ajax({
        url: '_js/data.php',
        success: function(data) {
            list.empty().html(data);
        }
    });
});
Šime Vidas
  • 182,163
  • 62
  • 281
  • 385
  • Keep in mind that with your `.delegate()` solution, you're replacing the `#listdata` element itself, so you'll lose the `.delegate()` handler. EDIT: You could do `list.parent().delegate('#listdata a.refresh','cli...` – user113716 Feb 14 '11 at 17:40
  • Unfortunately this is the first thing I tried to no luck. I think Sam's answer is along the right lines, in that **replaceWith** is removing the div. Unfortunately I'm still no nearer to the answer. – Paul Feb 14 '11 at 17:44
  • @Paul ... but if the .refresh elements are **not** inside the #listdata element, then you **don't** need to use live/delegate and just click is fine. – Šime Vidas Feb 14 '11 at 17:51
0

You'll need to change the href's on your links to <a href="#">...</a>. This prevents the browser from refreshing when you click the link.

If you're doing things this way, you'll also want to stick a "return false" at the end of the click handler to prevent bubbling.

Rui Jiang
  • 1,662
  • 1
  • 15
  • 25