Skip to main content

Double Click Action on Portal List Row

· 5 min read
Corey Sutton
Power Pages Icon

Users who are familiar with Dynamics and Power Platform Model Driven Apps expect a double-click action on grids and grid-like components. By default Power Apps portals does not provide a double-click action for entity lists that are rendered on a page, and as far as I am aware, there is no configuration option to enable this.

Jump To Solution

Configure an Entity List

Here is how I achieve a double click on an entity list:

  1. First decide on what action you want to happen when a user double-clicks. For my "Active" entity list, I want to open an advanced form to "edit" the record. So on my entity list record I configure the "edit action": Configure entity list action screenshot

  2. Then add some custom JavaScript to the entity list: Configure entity list script screenshot

$(".entity-grid.entitylist").on("loaded", function ()
{
const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;

const href = $(anchor[0]).attr("href");
if (href == null) return;

window.location.href = href;
}

const rows = $(".entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });
});

JavaScript Breakdown

The Goal

Attach a dblclick event to each entity list row <tr>

Step 1 - Determine when the entity list has loaded

If we try to attach the dblclick events after the document has loaded using $(document).ready() we encounter a problem, where the entity list rows have not yet finished loading. When quering for table rows <tr> we get an empty array.

The solution, find the entity list container and bind a function to the loaded event of the container:

$(".entity-grid.entitylist").on("loaded", function ()
{
// Do something when the entity list has loaded
});

Step 2 - Find and bind the entity list rows

Next we need to find the table rows <tr> for the entity list. There are multiple selectors and approaches to do this:

// 1. Direct selector
const rows = $$(".entity-grid.entitylist .view-grid table tbody tr");

// 2. Navigate children
const rows = $(event.currentTarget).find(".view-grid table tbody tr");

// 2. Navigate children, less specific
const rows = $(event.currentTarget).find("tbody tr");

Once we decide on our row retrival method we need to iterate the rows and bing the dblclick event to each row. For readability I will define a callback function named onDblClickRow:

const rows = $(".entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });

This is added to our loaded callback:

$(".entity-grid.entitylist").on("loaded", function ()
{
const rows = $(".entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });
});

Step 3 - Implement the onDblClickRow callback

Now we need to define an action to trigger when the row is double clicked. In my case I want to edit the record. We previously configured the edit action on the entity record, which should now be showing for each row in the action menu: Edit button

In essence, we want to click the edit button when a user double-clicks the row. We can achieve this by navigating down the DOM, starting from the <tr> that triggered the onDblClickRow event.

The jQuery function on() that we used in step 1 $(this).on("dblclick", onDblClickRow) takes a callback as the second paramenter. Lets define the callback function, called onDblClickRow:

const onDblClickRow = function (event) {
// Do something when the row is double-clicked
}

The callback function is passed an event object as a parameter. We use this to get a reference to the <tr> that tirggered the event using target.currentTarget or this (but I prefer to avoid this where possible):

const onDblClickRow = function (event) {
$(event.currentTarget)
}

The we apply the find() function to our <tr> to search for the "Edit" button. The "Edit" button is implemented as an <a> tag. We have only configured a single action, so only expect to find one tag, so will validate the result:

const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;
}

Finally we need to get the URL of the edit form for this particular record, so we fetch the href attribute from the <a> tag and redirect the user to that URL:

const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;

const href = $(anchor[0]).attr("href");
if (href == null) return;

window.location.href = href;
}

Solution

We add the onDblClickRow callback function to our loaded event callback and get the final result:

$(".entity-grid.entitylist").on("loaded", function ()
{
const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;

const href = $(anchor[0]).attr("href");
if (href == null) return;

window.location.href = href;
}

const rows = $(".entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });
});

Tip

If you have mutliple entity lists on a single page you may have to modify the selector specificity and page HTML:

$("#my-active-records-container.entity-grid.entitylist").on("loaded", function ()
{
const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;

const href = $(anchor[0]).attr("href");
if (href == null) return;

window.location.href = href;
}

const rows = $("#my-active-records-container.entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });
});

If you have multiple actions you may need to modify which <a> tag you select, rather than index [0]:

$(".entity-grid.entitylist").on("loaded", function ()
{
const onDblClickRow = function (event) {
const anchor = $(event.currentTarget).find("a");
if (anchor.length !== 1) return;

const href = $(anchor[0]).attr("href");
if (href == null) return;

window.location.href = href;
}

const rows = $(".entity-grid.entitylist .view-grid table tbody tr");
rows.each(function () { $(this).on("dblclick", onDblClickRow) });
});

You can even define a custom action / dialog / event by replacing the contents of onDblClickRow.