Introduction
In Power Pages (Earlier Power Apps Portal), OOB support for selecting/deselecting all grid rows in the “Lookup records” dialog is not found. Hence, I have built one client-side custom generic feature using Jquery, which will be reusable for all such “Lookup records” dialogs.
Background
This use case is regarding many-to-many relationships within 2 tables in Dataverse. In Power Pages, “Basic Form (Edit Mode)”, the association can be configured with another table, and on click of the “Associate” button, the “Lookup records” dialog is opened. This article will not discuss how to configure many-to-many table relationships and associations in Basic Form etc., as you may find articles online about it.
Client Side (Jquery) Code
Just add this custom piece of code to “Basic Form (Edit mode) > Addition Settings > Custom Javascript”, and it should work.
// Custom "Select / Unselect All" button for Lookup records Dialog
var SelectAllRecordButtonText = "Select All";
var UnselectAllRecordButtonText = "Unselect All";
var SelectUnselectAllRecordButtonId = "SelectUnselectAllRecords";
var isRunningCustomFeatureCode = false;
$(document).ready(function () {
// flag to check if new button is added already
var isSelectUnselectAllButtonAdded = $("#"+SelectUnselectAllRecordButtonId);
// find modal body element of dialog
var modalbody = $(".entity-associate").find(".modal-body");
// If button is not added already then add the button
if(isSelectUnselectAllButtonAdded && modalbody) {
modalbody.prepend('<button id="'+SelectUnselectAllRecordButtonId+'" aria-label="'+SelectAllRecordButtonText+'" class="primary btn btn-primary" tabindex="0" title="'+SelectAllRecordButtonText+'" type="button" onclick="SelectUnselectAllRecordsAction();">'+SelectAllRecordButtonText+'</button>');
}
// Bind event to "Selected Records" div to detect for any changes in div (especially if any child element is added or removed) and then perform action
// Action: Change button text based on child elements count in "Selected records" div
var selectedRecords = $(".selected-records");
if(selectedRecords) {
selectedRecords.bind("DOMSubtreeModified",function(){
if(!isRunningCustomFeatureCode) {
var selectedRecordsChildren = $(this).children();
if(selectedRecordsChildren.length > 0) {
// if "Selected records" div has records then show Unselect All button text
$("#"+SelectUnselectAllRecordButtonId).html(UnselectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("aria-label", UnselectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("title", UnselectAllRecordButtonText);
}
else {
// if "Selected records" div has no records then show Select All button text
$("#"+SelectUnselectAllRecordButtonId).html(SelectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("aria-label", SelectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("title", SelectAllRecordButtonText);
}
}
});
}
});
function SelectUnselectAllRecordsAction() {
// set flag to true so that not to perform any action in "DOMSubtreeModified event of 'Selected Records' div" when tr loop code running here
isRunningCustomFeatureCode = true;
// find grid table element
var viewgriddiv = $(".entity-associate").find(".modal-body").find(".entity-grid").find(".view-grid");
var tablegrid = viewgriddiv.find(".table");
// get button text
var currnetButtonText = $("#"+SelectUnselectAllRecordButtonId).html();
tablegrid.find("tbody tr").each(function() {
// Check if 'tr' is selected or not, with the help of css class
var isChecked = false;
if($(this).attr("class") == "selected info") {
isChecked = true;
}
else {
isChecked = false;
}
// if button click action is "Select All" and row is not selected only then click row
if(currnetButtonText == SelectAllRecordButtonText) {
if(!isChecked) {
$(this).click();
}
}
// if button click action is "Unselect All" and row is selected only then click row
if(currnetButtonText == UnselectAllRecordButtonText) {
if(isChecked) {
$(this).click();
}
}
});
// if current button text is 'Unselect All' then empty all child elements of "Selected records" div
// this is needed in case of like any record searched from Search box and selected
if(currnetButtonText == UnselectAllRecordButtonText) {
$(".selected-records").empty();
}
// if "Selected records" div has children then show button text as "Unselect All", if it is empty then show button text as "Select All"
var selectedRecords = $(".selected-records").children();
if(selectedRecords.length > 0)
{
// if "Selected records" div has records then show 'Unselect All' button text
$("#"+SelectUnselectAllRecordButtonId).html(UnselectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("aria-label", UnselectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("title", UnselectAllRecordButtonText);
}
else
{
// if "Selected records" div has no records then show 'Select All' button text
$("#"+SelectUnselectAllRecordButtonId).html(SelectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("aria-label", SelectAllRecordButtonText);
$("#"+SelectUnselectAllRecordButtonId).prop("title", SelectAllRecordButtonText);
}
// set flag to false, once tr loop code running here
isRunningCustomFeatureCode = false;
}
Summary
After adding the code, the Custom “Select / Unselect All” button will start appearing in the “Lookup records” dialog and is ready for action. Selected records are visible in OOB “Selected Records” div.
Happy Learning, Anywhere!