Categories
Advanced

How to Insert ‘Select All’ Button to a WordPress Table?

I wanted to share how I created a “Select All” button to a WordPress table. Generally, WordPress doesn’t have a button to select the entire current table. You can usually select only a prefixed number.

Basically, this is what the expected result should look like.

How to set it up?

After some work, I’m gonna walk you through the process. Its not hard to create the PHP side. So let’s focus on the javascript first.

Initially, create some variables:

var allSelected = false;
var itemCount = jQuery(".displaying-num").first().text();  var doAction1Text = jQuery("#doaction").val(); 
var doAction2Text = jQuery("#doaction2").val();

I simply got the values of the amount of items in the table and the text values of the submit buttons.

Now let’s create the new checkbox HTML:

var selectDropdown = 
'<div id="select-all-dropdown" style="display: inline-flex;"> \
  <input type="hidden" id="apply-on-everything-input" name="apply-on-everything"> \
  <span id="toggle-select-all-menu" class="ui-selectmenu-icon ui-icon ui-icon-triangle-1-s"></span> \
</div>';
var selectAllMenu = 
"<div id='select-all-menu' style='display: none';> \
  <button id='select-all-table-button' class='button' 
  style=''>All " + itemCount + "</button> \
</div>";

Notice that the menu has inline-flex display and that initially the menu itself has display none.

Next, I will detach the original checkbox and attach my menu instead:

var regularSelectAll = jQuery("#cb-select-all-1").detach();
jQuery("#cb").append(selectDropdown);
jQuery("#select-all-dropdown").append(regularSelectAll);
jQuery("#select-all-dropdown").after(selectAllMenu);

In order to get the proper look, you will need the following Cascading Style Sheets(CSS):

 #select-all-menu{
   margin-left: -10px;
   position: absolute;

   /* make the menu appear above the background: */
      z-index: 100;
 }

Finally, add some click event binding. I want that clicking on the dropdown arrow to toggle the appearance of the menu. I also want to click anywhere outside which results in closing the menu:

jQuery(document).on('click', function(e) {
   if(e.target.id == "toggle-select-all-menu"){
     jQuery("#select-all-menu").toggle();
   }else{
     jQuery('#select-all-menu').hide();
   }
  });

And finally, clicking the “Select All” button changes the submit button text and disables all of the checkboxes in the check column:

jQuery('#select-all-table-button').on("click", function(ev) {
  allSelected = !allSelected;
  ev.preventDefault();
  jQuery("#select-all-table-button").text(allSelected ? 
    "Deselect All" : "All " + itemCount);
  jQuery("#doaction").val(!allSelected ? doAction1Text : 
    doAction1Text + " (" + itemCount + ")");
  jQuery("#doaction2").val(!allSelected ? doAction2Text : 
    doAction2Text + " (" + itemCount + ")");


  jQuery("#apply-on-everything-input").val(allSelected);
  jQuery('.check-column 
    input[type=checkbox]').prop('checked', function(i, v) 
    { return allSelected; });
  jQuery('.check-column 
    input[type=checkbox]').prop('disabled', function(i, v) 
    { return allSelected; });
});

That’s it! We now have the UI ready. All we need to do now is to create the PHP side. For that, we have inserted the hidden input (Did you notice where we did that?) and now our form will also submit it with the key apply-on-everything . To use it we can just apply the filter edit_posts_per_page and return -1:

add_filter( "edit_posts_per_page", function($ppp){
   return -1;
});

So breaking it down, here is the PHP side (Assuming that we put the above into respective javascript and CSS files):

add_action('current_screen', function($screen){
  if($screen->id == "edit-product"){
    wp_enqueue_script( 'select_all_js', plugins_url( 
      'assets/js/check_all.js', __FILE__ ), array(), 1.3, 
      true );
    wp_enqueue_style( 'select_all_css', plugins_url( 
      'assets/css/check_all.css', __FILE__ ), array(), 
      1.4);
    if($_REQUEST['apply-on-everything']=="true"){
       add_filter( "edit_posts_per_page", function($ppp){
         return -1;
       });
    }
  }
});

You can see that I have targeted the product screen, but you can change that to any table you’d like.

Next up: how to make this asynchronous, such that requests don’t even have to reload the page? Stay tuned to find out!

Leave a Reply

Your email address will not be published. Required fields are marked *