Problem/Motivation

We recently upgraded from 4.1.2 to 4.1.4 and i see that a feature we were going to add on our own has been added to VBO now. This is to only enable action buttons if items are selected. Unfortunately this upgrade and that feature has now broken our vbo table.

It seems as though this only works if there is only 1 vbo table on the page. We have 2 vbo (in tabs) but single action button on only one of these works correctly by enabling/disabling based on the rows being checked or not. The other is disabled by default and now can not be enabled.

If a row is selected, when the page is refreshed, the state of the action button is set correctly. Oddly, even if the other table has no results (and therefore no checkboxes or buttons showing), the other table is still broken.

i do see that the toggleButtonsState js code is not working correctly in that anyItemsSelected is still 0 when selecting items on the broken table.

I'll see if i can debug further and possibly come up with a patch. My guess is selector for this needs to include table ID.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

liquidcms created an issue. See original summary.

liquidcms’s picture

Ah, my bad:

i do see that the toggleButtonsState js code is not working correctly in that anyItemsSelected is still 0 when selecting items on the broken table.

this is not true, the code is only being run on the 1 table. likely needs a .each() here somewhere.

liquidcms’s picture

i think the bind function is binding the last form that is hit to all the checkboxes rather than just the ones for that form. jquery is definitely not my strong point; but rather than using this.vbo_form everywhere, i changed the code to this:

    bindCheckboxes: function () {
      var selectionObject = this;
      var vbo_form = this.vbo_form;
      var checkboxes = $('.form-checkbox', vbo_form);
      checkboxes.on('change', function (event) {
        selectionObject.toggleButtonsState(vbo_form);
      });
    },

    toggleButtonsState: function(vbo_form) {
      // If no rows are checked, disable any form submit actions.
      var checkedCheckboxes = $('.form-checkbox:checked', vbo_form);
      var buttons = $('[id^="edit-actions"] input[type="submit"], [id^="edit-actions"] button[type="submit"]', vbo_form);
      var selectedAjaxItems = $('.vbo-info-list-wrapper li', vbo_form);
      var anyItemsSelected = selectedAjaxItems.length || checkedCheckboxes.length;
      if (this.$actionSelect.length) {
        var has_selection = anyItemsSelected && this.$actionSelect.val() !== '';
        buttons.prop('disabled', !has_selection);
      }
      else {
        buttons.prop('disabled', !anyItemsSelected);
      }
    },

and this fixes the issue. I'd create a patch; but guessing a cleaner way to do this??

liquidcms’s picture

hmm, better, but not perfect. Default setting on page refresh is not always correct.

liquidcms’s picture

the following code seems to work pretty reliably but i suspect there is a cleaner selector that could be used so haven't created a patch. Could do though if of any help to anyone.

bindCheckboxes: function () {
      var selectionObject = this;
      var vbo_form = this.vbo_form;
      var checkboxes = $('.form-checkbox', vbo_form);
      checkboxes.on('change', function (event) {
        selectionObject.toggleButtonsState(vbo_form);
      });
    },

    toggleButtonsState: function(vbo_form) {
      // If no form passed in; use this.form
      if (typeof vbo_form === 'undefined') {
        vbo_form = this.vbo_form;
      }
      // If no rows are checked, disable any form submit actions.
      var checkedCheckboxes = $('.form-checkbox:checked', vbo_form);
      var buttons = $('[id^="edit-actions"] input[type="submit"], [id^="edit-actions"] button[type="submit"]', vbo_form);
      var selectedAjaxItems = $('.vbo-info-list-wrapper li', vbo_form);
      var anyItemsSelected = selectedAjaxItems.length || checkedCheckboxes.length;
      if (this.$actionSelect.length) {
        var has_selection = anyItemsSelected && this.$actionSelect.val() !== '';
        buttons.prop('disabled', !has_selection);
      }
      else {
        buttons.prop('disabled', !anyItemsSelected);
      }
    },
graber’s picture

dunebl’s picture

The patch in #5 is solving my problem.
Many Thanks!

graber’s picture

Status: Active » Needs review

@DuneBL, that's great but please try the diff from the MR (https://git.drupalcode.org/project/views_bulk_operations/-/merge_requests/39.diff), it's a cleaner solution as it creates a new independent selection object for every form.

@liquidcms thank you for working on this as well!

dunebl’s picture

Hello,
I confirm that MR39 is solving this issue.
Many thanks!!

graber’s picture

Status: Needs review » Fixed

Thanks!

  • Graber committed aabb46a on 4.1.x
    Issue #3300794 by Graber, liquidcms, DuneBL: enable actions only when...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.