1
<input id='lightson' class="buttonl" type="button" value="On" />
<input id='lightsoff'  class="buttonl" type="button" value="Off" />
<p class="status2"></p>

<script type="text/javascript">
$('#lightson').click( function(){
    $.get('http://<?php echo $_SESSION['ip']?>/?2', {}, callbacka());
    function callbacka(){
        $('.status2').load('status2.php').delay(3000).queue(function() {
            $(this).empty();
        });
    }
});

$( '#lightsoff' ).click( function () {
    $.get('http://<?php echo $_SESSION['ip']?>/?3', {}, callbackb());
    function callbackb(){
        $('.status2').load('status3.php').delay(3000).queue(function() {
            $(this).empty();
        });
    } 
});
</script>

When I click lightson, I want to load something in to my div and after three seconds to empty it. Also when I click lightsoff I want to load something else and after three seconds to empty it because both buttons use the same div.

This code works only once. When my page loads and I click one of two buttons (it doesn't matter which button) it works, but if I click the other button, it loads the info in the div but doesn't empty it.

My new code that works for the time is:

<input id='lightson' class="buttonl" type="button" value="On" />
<input id='lightsoff'  class="buttonl" type="button" value="Off" />
<p class="status2"></p>

<script type="text/javascript">
$('#lightson').click(function(){
    $.get('http://<?php echo $_SESSION['ip']?>/?2', {}, callbacka());
    function callbacka() {
        $('.status2').load('status2.php').delay(3000).queue(function(){
            $('.status2').empty().dequeue();
        });
    }
});

$('#lightsoff').click( function () {
    $.get('http://<?php echo $_SESSION['ip']?>/?3', {}, callbackb());
    function callbackb(){
       $('.status2').load('status3.php').delay(3000).queue(function() {
           $('.status2').empty().dequeue();
       });
    } 
});
</script>

Description for what I want with the above code: I have two button. When I click one of them I want to send the value "2" to a url and in the class status2 to load the content of status2.php and after 3secs to empty the class status2. And so on if I click the other button. I think the above code do the job. If I remove the "()" from the callback when I click the button only send the value "2" and nothing else happens.

thecoshman
  • 8,394
  • 8
  • 55
  • 77
alexgeorg86
  • 145
  • 1
  • 1
  • 8

3 Answers3

2

Don't put () after callbacka/callbackb. This calls them and sets the callback for $.get, to the return value (undefined in your case).

$.get( 'http://<?php echo $_SESSION['ip']?>/?2', {}, callbacka );

Also, delay only works for animations. To wait 3 seconds after load is done, use setTimeout inside the load callback.

$('.status2').load('status2.php', function() {
    var $this = $(this);
    setTimeout(function(){
       $this.empty();
    }, 3000);
});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • `.delay()` works for anything that is queued. It doesn't necessarily need to be an animation. –  Dec 25 '11 at 05:27
  • @amnotiam: Unless I'm doing something wrong, it doesn't seem `delay` works with arbitrary functions added to the queue. http://jsfiddle.net/Zxqt7/ – gen_Eric Dec 25 '11 at 17:14
  • @Rocket: I've got to admit your example stumped me for a bit because I'm not accustomed to working with custom queue names and passing an Array of functions. [Here's an updated example](http://jsfiddle.net/Zxqt7/2/) where I got rid of the Array, gave the custom name to the `delay` calls, and manually dequeued inline. The initial `delay` also needed to be dequeued manually apparently because it's not part of the default `fx` queue. –  Dec 25 '11 at 18:09
  • 1
    @amnotiam: Cool, so `delay` does work for all queues, not just the `fx` queue. – gen_Eric Dec 25 '11 at 20:16
1

To get this to work with dynamically added content, wire your events with on

 $(document).on("click", "#lightson", function () {
    var $status = $('.status2');
    $status.load('status2.php', function() {
        setTimeout(function() { $status.empty(); }, 3000); 
    });
 }

I tested this successfully, but I don't think I'd be able to get the ajax load to work in a fiddle :)

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
  • I don't think `#lightson` is being re-loaded. Only the contents of `.status2`. – gen_Eric Dec 25 '11 at 03:07
  • Actually, inside the `load` callback, `this` **is** the DOM element that `load` was called on. The data returned from `load` is passed to the callback as the 1st parameter. – gen_Eric Dec 25 '11 at 03:10
  • 1
    @Rocket - you're right - thank you. Of course `this` is something else when the setTimeout callback is called, which is why I needed $status :) – Adam Rackis Dec 25 '11 at 03:14
  • @Rocket - I think you're right on the other. I +1'd you accordingly. – Adam Rackis Dec 25 '11 at 03:20
  • Hi Adam. If you don't mind me saying, while event delegation is good, document level event delegation is usually not the best idea. Every click that takes place on the page will need to be tested against every selector associated with the `document`. For handlers associated with one specific element, it's usually best to bind it directly, or at least to narrow the delegate down to a more local container. :) –  Dec 25 '11 at 05:31
  • @amnotiam - true, I know. Instead of `document` you want the most narrow container that will contains all of the items that will be clicked. I just left this answer as is since Rocket had already identified OPs problem. Hopefully he'll accept it now... – Adam Rackis Dec 25 '11 at 05:33
  • ...or maybe you thought those elements were being loaded dynamically. –  Dec 25 '11 at 05:33
  • Yeah, I see that I should have taken a closer look at the comments. –  Dec 25 '11 at 05:34
  • @amnotiam - yes - actually. OP said that subsequent clicks didn't work, so I foolishly assumed the thing he was clicking on was dynamically loaded. I put $(document).on since that'll always work, I just left off the part about optimizing it to use something more narrow than document. – Adam Rackis Dec 25 '11 at 05:34
  • @amnotiam - and I never mind you pointing out something like this :) – Adam Rackis Dec 25 '11 at 05:35
  • Well I ought to have known that you understood delegation well enough. I've seen you give quality answers here. –  Dec 25 '11 at 05:37
  • @amnotiam - see if you have anything to add to this question -> not sure if you have a slicker way than my answer http://stackoverflow.com/questions/8628059/javascript-check-if-superset-or-equal/8628068#8628068 – Adam Rackis Dec 25 '11 at 05:40
  • Thanks for all the answers! I tried to remove from the callbacks the '()' but now the status2 div doesn't show anything...Sorry I'm very new to all this..Any other suggestion? – alexgeorg86 Dec 25 '11 at 17:19
  • Ok I think I made it! The callbacks need the '()' because without it the function for some reason can't load. So I think the problem was the delay().The code now is: `$( '#lightson' ).click( function () { $.get( 'http:///?2', {}, callbacka() ); function callbacka() { $('.status2').load('status2.php', function() { var $this = $(this); setTimeout(function(){ $this.empty(); }, 3000); }); } } );` – alexgeorg86 Dec 25 '11 at 17:38
  • @alexgeorg86: If you want the callback delayed, then you need to remove the `()` otherwise they'll be immediately invoked. The trouble you had was that you're using `queue()`, but you're not `dequeue`ing each time. This means any future delays or animations will be stuck. Remove the `()`, and inside the callbacks do `$(this).empty().dequeue();` –  Dec 25 '11 at 18:13
  • @am not i am: Ok the dequeue() solve my problem but with the '()' after callback. Without '()' after callback when I click the button, in my div I cant see anything (content) that must load and disappear after 3secs. So I need the '()'. – alexgeorg86 Dec 25 '11 at 18:33
  • @alexgeorg86 - using `delay` `queue` and `dequeue` here shouldn't be necessary. You don't want `()` after your callback. `$.get( 'http:///?2', {}, callbacka );` will run callbacka after the load is complete. To put a 3 second delay in callbacka just use a simple setTimeout like Rocket and I put in our answers. – Adam Rackis Dec 25 '11 at 19:25
0
<script type="text/javascript">
    $( '#lightson' ).click( function () {
            $.get( "http://<?php echo $_SESSION['ip']?>/?2" );
            callbacka();
    } );

     function callbacka() {           

                $( '.status2' ).load( 'status2.php' ).delay( 3000 ).queue( function() {
                    $('.status2').empty().dequeue();
                });

    }

    $( '#lightsoff' ).click( function () {
            $.get( 'http://<?php echo $_SESSION['ip']?>/?3' );
            callbackb();
    } );

    function callbackb() {

                $( '.status2' ).load( 'status3.php' ).delay( 3000 ).queue( function() {
                    $( '.status2' ).empty().dequeue();
                });

    }
</script>
alexgeorg86
  • 145
  • 1
  • 1
  • 8