Calling a registered javascript function N-times

Myke623

Well-known member
I've created some custom buttons (toggle yes/no) for use in a form:

toggle-yes-no.webp
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.
 
You can maybe do something similar to:

Code:
$.each($allButtons, function(button)
{
    XenForo.Foo.ToggleYesNo(button);
});
 
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.
 
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
 
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?
 
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.
 
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?
 
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?
Yeah, I think this is probably the best way.
 
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?
 
Top Bottom