• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Calling a registered javascript function N-times

Myke623

Active member
#1
I've created some custom buttons (toggle yes/no) for use in a form:

toggle-yes-no.PNG
There are 19 buttons in total, with the first 3 selected ('yes') as shown.

The javascript function to handle the toggle functionality works as desired, changing both the appearance (class) and value (hidden input) on click:

Code:
XenForo.Foo =
{
   ToggleYesNo: function($handle)
   {
     $handle.on('click', function(){
       var $e = $(this),
         $hiddenVal = $e.find('#' + $e.data('id'));
    
       if ($e.hasClass('no')){
         $e.removeClass('no').addClass('yes');
         $hiddenVal.val('yes');
       } else {
         $e.removeClass('yes').addClass('no');
         $hiddenVal.val('no');
       }
     });
   }
};

XenForo.register('.ToggleYesNo', 'XenForo.Foo.ToggleYesNo');
This function is registered for each button. In the cases where all buttons need to be enabled, rather than have the user click 19 times, I would like to have another button that performs a Toggle All functionality.

Essentially, I'd like to call the XenForo.Foo.ToggleYesNo() function multiple times when a (new) button is clicked. To do this, I created a new button button with the following function, ToggleAll, registered:
Code:
    ToggleAll: function($handle)
    {
        $handle.on('click', function(){
            var $e = $(this),
                $allButtons = $e.find('.ToggleYesNo');
          
            XenForo.Foo.ToggleYesNo($allButtons);

        });
    }
But this doesn't work. I need to somehow trigger the on-click within the AppliesYesNo() function multiple times (for every button).

Any help with the above would be appreciated.
 

Chris D

XenForo developer
Staff member
#2
You can maybe do something similar to:

Code:
$.each($allButtons, function(button)
{
    XenForo.Foo.ToggleYesNo(button);
});
 

Myke623

Active member
#3
I know this feedback isn't very helpful, but when using:
Code:
        ToggleAll: function($handle)
        {
            $handle.on('click', function(){
                var $e = $(this),
                    $allButtons = $e.find('.ToggleYesNo');
               
                $.each($allButtons, function(button)
                    {
                       XenForo.Foo.ToggleYesNo(button);
                    });

            });
        }
It results in the ToggleYesNo not even being called.
 

thedude

Well-known member
#4
I know this feedback isn't very helpful, but when using:
Code:
        ToggleAll: function($handle)
        {
            $handle.on('click', function(){
                var $e = $(this),
                    $allButtons = $e.find('.ToggleYesNo');
              
                $.each($allButtons, function(button)
                    {
                       XenForo.Foo.ToggleYesNo(button);
                    });

            });
        }
It results in the ToggleYesNo not even being called.
ToggleYesNo is not actually doing the toggling when called, just setting up the click binding. Stick an alert (or console.log) directly under the opening curly brace for ToggleYesNo and you should see it getting called when you run the snippet @Chris D gave you in ToggleAll
 

Myke623

Active member
#5
ToggleYesNo is not actually doing the toggling when called, just setting up the click binding. Stick an alert (or console.log) directly under the opening curly brace for ToggleYesNo and you should see it getting called when you run the snippet @Chris D gave you in ToggleAll
Actually, that's exactly what I did to confirm that it wasn't being called! :)

It was getting late last night so I couldn't continue debugging, but I suspect that my $allButtons is empty, hence the $.each doesn't get a chance to iterate. Now that I think about it, the way I've defined $allButtons is most likely wrong as it assumes that all the buttons are descendants of $(this), and they're not.

Once I get home I'll try changing $allButtons = $e.find('.ToggleYesNo') to just $allButtons = $('.ToggleYesNo'). Hopefully, that'll select all the buttons with the ToggleYesNo class, right?
 

Chris D

XenForo developer
Staff member
#6
Hopefully, that'll select all the buttons with the ToggleYesNo class, right?
Indeed, this is what I was going to suggest earlier but I got busy. Give that a try... break it down. Work out what $allButtons contains and go from there.
 

Myke623

Active member
#7
Getting back to the point @thedude raised, once I do call the ToggleYesNo within the .each loop, nothing will happen because it only contains the click binding. So, how does one go about triggering another 'click' event so that this function will execute?

Or, should I define a separate function that does the toggling? This can then get called during the click binding for ToggleYesNo, and also called multiple times for the ToggleAll?
 

Myke623

Active member
#9
Here's a jsfiddle I've been playing with in my "down time" while at work ;)

For now, the ToggleAll button just outputs the text of the individual buttons to the console.log. How can I get it to actually toggle everything?