0

I have a function that is run on a generic table, it can't be specific, it needs to be able to be run on many different tables. The problem I'm having is if it's run on multiple tables on the same page. The click events fire just fine, but they only operate on the check elements in the final table, not the check elements within the table they were supposed to work on.

Here's the code:

            $parent = $table.parents('div.ibox').find('div.ibox-title');
            $select_all = $parent.find('button.select_all');
            $deselect_all = $parent.find('button.deselect_all');
            $input_delete = $table.find('input.delete');

            if ($table.find('input.delete').length >= 2) {
                $select_all.removeClass('hidden');
            } else {
                $select_all.addClass('hidden');
                $deselect_all.addClass('hidden');
            }

            $select_all.on('click', function(event) {
                $input_delete.each(function() {
                    $(this).prop('checked', true).trigger('change');
                    $select_all.addClass('hidden');
                    $deselect_all.removeClass('hidden');
                });
            });

            $deselect_all.on('click', function(e) {
                $table.find('input.delete:checked').each(function() {
                    $(this).prop('checked', false).trigger('change');
                    $deselect_all.addClass('hidden');
                    $select_all.removeClass('hidden');
                });
            });

$table is a variable containing the $('table') element the function is being run on, it's passed into the function.

Just wondering if anyone has any ideas on how to get the click elements to fire on the checkboxes within the table they are supposed to, and not the final table on the page.

Arak Tai'Roth
  • 408
  • 1
  • 7
  • 24

1 Answers1

1

Assuming you haven't omitted any code from your function other than the actual function someFunc() { and closing } part, these lines:

        $parent = $table.parents('div.ibox').find('div.ibox-title');
        $select_all = $parent.find('button.select_all');
        $deselect_all = $parent.find('button.deselect_all');
        $input_delete = $table.find('input.delete');

...all declare (or update) global variables. So after the function has been run for several different tables, those variables will continue to reference the last table's elements.

Those variables should all be declared with var, making them local to your function. Then your click event handlers will be referring to their own variables and not sharing global variables. (The click handlers can continue to refer to local variables in their containing scope even after the containing function completes, because closures.)

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
  • Thanks so much, this did it for me. Surprisingly, I've never had an issue with global and local variables before, so this is new for me. Appreciate the time and help. – Arak Tai'Roth Apr 12 '17 at 03:24
  • You're welcome. As a general rule, always declare all variables with `var` (or the newer `let` or `const`), *including* global variables (which obviously would have to be declared outside of any functions), because that makes it clear to people reading the code that you've declared globals on purpose rather than just accidentally left out the `var` from what should've been local variable declarations. – nnnnnn Apr 12 '17 at 03:29
  • P.S. You may also consider using [strict mode](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode), in which case accidental globals throw an error - which is a *good* thing because it helps you spot bugs immediately. – nnnnnn Apr 12 '17 at 03:31
  • Awesome, didn't know that either. You learn something new every day. Thanks so much for your help. – Arak Tai'Roth Apr 12 '17 at 04:06