Scully
Scully

Reputation: 1058

My jQuery only works after page refresh

My website has a list of games. One feature is being able to "watch" games. It's working well, but I can't reverse an action (watch/unwatch) unless I refresh the page.

Here's my jQuery:

$('.watch').click(function(e) {

    e.preventDefault();

    var game_id = $(this).data('game_id');
    $('#game-' + game_id + ' .watch').addClass('unwatch').removeClass('watch');

});

$('.unwatch').click(function(e) {

    e.preventDefault();

    var game_id = $(this).data('game_id');
    $('#game-' + game_id + ' .unwatch').addClass('watch').removeClass('unwatch');

});

Any ideas? Perhaps I can improve my code as well? Still learning jQuery/Javascript.

Thanks!

Upvotes: 3

Views: 1183

Answers (3)

Zainul Abdin
Zainul Abdin

Reputation: 835

Divide your click event in two different functions

use following jQuery code

    //call watch to bind watch click event
    watch();

    // watch method to bind watch class click event
    function watch(){
      $('.watch').click(function(e) {

        e.preventDefault();

        var game_id = $(this).data('game_id');
        $('#game-' + game_id ).addClass('unwatch').removeClass('watch');

        //bind unwatch class click event
        unwatch();
      });
    }

// unwatch method to bind unwatch class click event
    function unwatch(){
      $('.unwatch').click(function(e) {

        e.preventDefault();

        var game_id = $(this).data('game_id');
        $('#game-' + game_id ).addClass('watch').removeClass('unwatch');

        //bind watch class click event
        watch();
      });
    }

Upvotes: 0

jillro
jillro

Reputation: 4559

When you write the line $('.watch').click(callback); you attach callback to all element having .watch class at the moment of that line execution. When you change later the class of an element from .watch to .unwatch, it is not attached to callback you setted for .unwatch elements before.

You need to have a class .game for all you games and then :

$('.game').click(function(e) {

    e.preventDefault();

    var game_id = $(this).data('game_id');

    if($('#game-' + game_id).hasClass('unwatch')) {
        $('#game-' + game_id).addClass('watch').removeClass('unwatch');
    } else if ($('#game-' + game_id).hasClass('watch')) {
        $('#game-' + game_id).addClass('unwatch').removeClass('watch');
    }
});

Upvotes: 2

adeneo
adeneo

Reputation: 318182

The event handlers are attached on first page load to the elements matching the selector at that point in time, changing the classes later does not change the event handlers in any way, so you have to think completely different for a toggle functionality

$('.watch').click(function(e) {
    e.preventDefault();

    var game_id = $(this).data('game_id');

    if ( $(this).data('flag') ) {
        $('#game-' + game_id + ' .watch').toggleClass('watch unwatch');
    }else{
        $('#game-' + game_id + ' .unwatch').toggleClass('watch unwatch');
    }

    $(this).data('flag', !$(this).data('flag'));

});

Upvotes: 0

Related Questions