views:

51

answers:

2

Hi,

I have a hashmap that I have created to control the events for buttons. It is defined as so:

var Signage_Manager = {

init: function() {

    Signage_Manager.buttonActions.set_events();

},
buttonActions: {
    buttons: {

        '#add_product': {action: 'navigate', href: '/manager/add_product'},
        '.back_to_dashboard': {action: 'navigate', href: '/manager/dashboard'}

    },
    set_events: function() {
        for(var button in Signage_Manager.buttonActions.buttons){   
            if(Signage_Manager.buttonActions.buttons[button].action == 'navigate') {
                $(button).live('click', function() {
                    console.log(Signage_Manager.buttonActions.buttons[button].href);                                                 
                });
            }
            else {
                $(button).live('click', function() {
                    //
                    console.log('not navigate');                                                     
                });
            }
        }
    }
}
};

The problem is when I click the 'add_product' button, it tries to use the href '/manager/dashboard', instead of the '/manager/add_product' string that is in the defined row.

Can anyone offer a hand here?

A: 

Inside the live() call you have a reference to the button variable of the outer scope. When you click a button and the anonymous function gets executed the loop has already finished so button equals the last element of the hash table. You have to store the hash table element for each button.

A possible solution, using the data() method, could be:

$(button).data("button", Signage_Manager.buttonActions.buttons[button]).live('click', function() {
    console.log($(this).data("button").href);                            
});
Álvaro G. Vicario
+2  A: 

Because of closure your live functions will close over the same button variable, which changes in every iteration. And so at the end all event handlers will use the same button: the last one. In order to keep the button name, you can create an inner scope for the event handlers so as to ensure that each function will have its own jQuery selector.

if (Signage_Manager.buttonActions.buttons[button].action == 'navigate') {
  (function(button) {
    $(button).live('click', function () {
      console.log(Signage_Manager.buttonActions.buttons[button].href);
    });
  })(button);
}
galambalazs
This is a nice solution.
Álvaro G. Vicario
thank you so much, worked like a charm!
seacode