Skip to content

Power Pages: Multiselect List

Nicholas Hayduk May 31, 2026 2 Min.To Read

I recently received a question from Gil Shalem about adding bulk edit capabilities to a Power Pages List. Nothing like that exists out of the box, so if this is a requirement on your project, you’ll need to explore using some custom code to accomplish this. Over the next few blog posts, I’ll work through some of the pieces you could use to add bulk edit capabilities to a list. To get started, let’s look at how you can allow users to select multiple rows of the list.

Lists in Power Pages don’t have multiselect capabilities out of the box. So if we want users to be able to select multiple rows and make a bulk edit, we need users to be able to select multiple rows. In this post, we’ll look at how we can accomplish that using the classic (non-modern) lists.

My goal for this post is to keep it simple and to keep the code to a minimum. I’m not going to use React or TypeScript – instead, I’m going old school, by using jQuery, along with Bootstrap v5 components.

The Plan

Here is what we intend to do:

  • We are going to add a column to the front of every row that contains a checkbox – this will be the primary way to select a row.
  • We are going to add an area above the list that shows all of the currently selected items. Users should be able to remove items from being selected in this area. This area should be hidden if no rows are selected.
  • We will have an object called selectedRows that contains the ID of the selected rows, which we’ll use in future posts to enable bulk edit.

The primary challenge: classic lists have paging. So we need to be careful to handle what happens as the user switches between pages, like making sure that our list of selected items remains accurate, and that the checkbox for each row accurately reflects whether that row is currently selected.

The Code

Based on those considerations, I’ve created the following code:

$(document).ready(function () {
    // create an area to show selected rows
    const selectedCard = $('<div class="card"><div class="card-body"></div></div>').hide();
    // a variable to keep track of all currently selected rows
    const selectedRows = {};
    $(".entitylist.entity-grid").on("loaded", function () {
        const list = $(this);
        // handle adding a blank cell to the header for the checkbox column
        $(this).children(".view-grid").find("thead tr").each(function () {
            // this event fires for each page of data, but the header is reused, so only add the cell once
            if ($(this).find('.multiselectHeaderColumn').length == 0) {
                $('<td class="multiselectHeaderColumn"></td>').prependTo(this);
            }
        });
        $(this).children(".view-grid").find("tbody tr").each(function () {
            // grab the name and id of the current row
            const name = $(this).data('name');
            const id = $(this).data('id');
            // create a checkbox used to make the multiselect interface
            var checkbox = $('<input class="multiselectCheckbox" type="checkbox" />')
                // if the id exists in the object, ensure the checkbox begins checked
                .prop('checked', selectedRows[id])
                .on('click', function() {                    
                    if ($(this).is(':checked')) {
                        // create a badge to display the currently selected rows
                        const badge = $('<span class="badge">' + name + '</span>');
                        // add a button to the badge that, when clicked, unselects the row
                        const removeButton = $('<button class="btn btn-primary btn-sm">X</button>').on('click', function() {                            
                            selectedRows[id].remove();
                            delete selectedRows[id];
                            list.find('tr[data-id="' + id + '"] input.multiselectCheckbox').prop('checked', false);
                        });
                        badge.append(removeButton);
                        selectedRows[id] = badge.appendTo(selectedCard.find('.card-body'));
                        selectedCard.show();
                    } else {                        
                        selectedRows[id].remove();
                        delete selectedRows[id];
                        // if there are no selected item, hide the area
                        if (!Object.keys(selectedRows).length) selectedCard.hide();
                    }
                });                
            $('<td />').append(checkbox).prependTo(this);
        });
    }).prepend(selectedCard);
}); 

With that code in place, we get a rudimentary multiselect interface that works even when users go between different pages in the list:

Leave a Reply

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

Back to top