I have created a custom table using a Form API tableselect element, and within my table, I have embedded a checkbox form element that is checked based on an entity field (see here for details). The checkbox functionality works fine. The problem I've discovered, though, is that the Select/Unselect All checkbox that is created as the first column in the table also affects my custom checkboxes, in that when I click on the select/unselect all checkbox, it also selects/unselects all the checkboxes in my column.

The offending code is in the tableselect jQuery behavior, and it's one line that makes the assumption that the only checkbox a tableselect element will ever have is the one that is part of the element:

if ($(event.target).is('input:checkbox')) {
  // Loop through all checkboxes and set their state to the select all checkbox' state.
  checkboxes.each(function () {
    this.checked = event.target.checked;
    // Either add or remove the selected class based on the state of the check all checkbox.
    $(this).closest('tr').toggleClass('selected', this.checked);
  // Update the title and the state of the check all box.

As the comment says, it does all checkboxes. Sigh.

From what I've been reading, my only option is to use hook_js_alter to replace the behavior with my own version. However, that seems like a bit of overkill just to change a couple lines. Is there another way to keep this behavior from affecting my checkbox field, or am I understanding correctly?


I ended up doing what I suggested, and overriding with my own custom version of tableselect.js

 * Implements hook_js_alter().
function language_dashboard_js_alter(&$javascript) {
  // Override core tableselect.js with custom version.
  $javascript['misc/tableselect.js']['data'] = drupal_get_path('module', 'language_dashboard') . '/js/language_dashboard_tableselect.js';

just to tweak this one line from this:

checkboxes = $('td input:checkbox:enabled', table).click(function (e)

to this:

checkboxes = $('td input:checkbox:enabled', table).not("input[id*='staging_only']").click(function (e)

by adding the .not() selector. It seems like a lot of code copying just for that one modification, but as of now, I don't see any other way.

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.