Posted in JavaScript/jQuery Plugins, Power Apps Portals

Power Pages – Autocomplete Lookup / Dropdown

Basic Forms and Advanced Forms in Power Pages are an amazing way to quickly expose Dataverse data to external users for data manipulation.

The way Power Pages works is by reading the Dataverse form metadata to render the controls on the page. Using Basic Form/Advanced Form Metadata, Power Pages also allows us to control styling and behaviour to controls.

One common question I receive is how to convert a dropdown into a autocomplete control, and that’s what we’ll see in this post. Here is an example of what we are about to achieve:

It’s probably obvious, but worth mentioning that this logic is only applicable for the following type of controls:

  • Choices (OptionSet)
  • Lookups (rendered as dropdown via metadata)

I will describe here what my code below is doing, and the things I have considered when putting this together:

  • The function ConvertSelectToAutocomplete takes two arguments:
    • selectName: the schema name of your column (i.e. primarycontactid)
    • selectPlaceholder: optional parameter if you want a placeholder text when it’s blank (i.e. Please start typing…)
  • The function will copy a few elements from the original select element, for example Classes and Readonly attributes
  • Then I am creating a new <input> element pointing to an empty <datalist> and adding this element to the page
  • Now what I do is loop through all <option> within the original <select> element and add the options to the new datalist
  • The original <select> element is no longer necessary, so we can hide it from the page with a .hide()

All actions above are sufficient to convert your dropdown to a HTML5 autocomplete dropdown, but there are still a few more things to get the full solution working properly:

  • If the record being opened already contains value in the Choices/Lookup column, we need to make sure to populate with the original value. For this we will check the current value and try to find the correspondent item within the dataset
  • The last action here is to attach a logic to the OnChange event, the reason for this is that we need to make sure to keep the original column element in the page up to date with the newly selected value as in the form submit is the original element that will be sent to the server

Before we get to the full code, it’s important to note a few things:

  1. Dataset value
    • The control uses a dataset for holding the options available in the dropdown. The dataset value attribute is the text displayed within the dropdown, so I am creating a separate data-value to hold the actual id/value of the item
    • Because of that, every time we need to get the data-value, it has to be done by finding the element within the dataset list (by text)
    • In other words, for this to work properly, your dataset needs to have unique texts, otherwise it might find the wrong item
  2. Invalid entry
    • By default, this control allows you to add an entry that is not listed within the dataset, so we need to prevent this from happening
    • In my code, what I am doing is simply ignoring and removing the selected text, however you can add an error message in the code if it you prefer
$(document).ready(function () {
    ConvertSelectToAutocomplete("<your optionset/lookup dropdown here>");
});

function ConvertSelectToAutocomplete(selectName, selectPlaceholder) {
    selectPlaceholder = selectPlaceholder ?? "";
    var selectElement = $("#" + selectName);
    var selectElementClass = selectElement.attr("class");
    var readonly = $(selectElement).attr("readonly") ?? "";
    var autoCompleteElementId = selectName + "-autocomplete";
    var autoCompleteDatasetId = selectName + "-data";
    var autoCompleteElement = '<input name="' + autoCompleteElementId + '" id="' + autoCompleteElementId + '" class="' + selectElementClass + '" list="' + autoCompleteDatasetId + '" placeholder="' + selectPlaceholder + '" ' + readonly + '><datalist id="' + selectName + '-data"></datalist>';
    var options = "";

    $(selectElement).parent().append(autoCompleteElement);
    $("#" + selectName + " option").each(function (index, o) {
        options += '<option data-value="' + o.value + '" value="' + o.text + '"/>';
    });
    $("#" + autoCompleteDatasetId).html(options);

    $(selectElement).hide();

    var currentSelectedValue = $(selectElement).val();
    if (!!currentSelectedValue) {
        $("#" + autoCompleteElementId).val($(selectElement).find("option:selected").text());
    }

    $("#" + autoCompleteElementId).on("change", function () {
        var selectedValue = $("#" + autoCompleteDatasetId + " option[value='" + $("#" + autoCompleteElementId).val() + "']").attr("data-value");
        selectElement.val(selectedValue);
        if (typeof selectedValue === "undefined") {
            $("#" + autoCompleteElementId).val("");
            // optionally you can add an error message here
        };
    });
};

Conclusion

This is a nice client-side script logic to enhance the user experience in your Portals. I probably wouldn’t use this in every scenario, if you have just a few options like Yes/No/Blank, I would probably not use this; but if your list goes beyond that with 10+ options, this might improve the way users are filling in forms.

Posted in Uncategorized

Power Pages – Power Apps Portals is now Power Pages

Microsoft Build 2022 is coming the announcements of many things throughout the Microsoft stack. I highly recommend catching-up on the sessions for your favourite topics here: https://mybuild.microsoft.com/en-US/home

Power Pages

Power Apps Portals is now Power Pages – and of course this is what I am here to talk about: Announcing Microsoft Power Pages: Build secure, low-code websites | Microsoft Power Pages

This is definitely the most exciting announcement for me personally. Microsoft has put a lot of investment on Power Apps Portals over the years and while it has been part of the Power Apps products for a few years, it is now becoming a product of its own within the Power Platform under the new name of Power Pages.

You may think this is just a product re-branding (as we all know Microsoft loves to do that), but it is a bit more than that, community forum will now have its own dedicated forum now, similar to Power BI or Power Automate, new Site Templates will be available to accelerate your implementation, a complete new Design Studio with many new capabilities and many more. I see all of this is a reflection of the growth of the platform and as a community member very much involved in this product, I am really happy to see this evolution.

What does this mean to your current Portals?

The base of the Portals is still the same, so there is no compatibility issue between them. Microsoft haven’t released yet details on migration, the only potential impact I can think of would be on the domain of your portals (from .powerappsportals.com to .powerpages.com). This should be more clear over the upcoming weeks.

Posted in Entity List, JavaScript/jQuery Plugins, Power Apps Portals

Power Apps Portals – Remove default value on Lookup Modal

Following up on a comment from another post: Custom Lookup filter, I feel like this deserves its own dedicated article.

A Lookup column in a Basic Form/Advanced Form in Power Apps Portals is represented in a Web Page by a web control that contains a modal associated to it. This modal gives us the ability to select and filter records for that entity.

If your Lookup column is empty, when clicking on the magnifying glass, the Portals will automatically select the first record:

This behaviour might not be what you are looking for, so in this article I wanted to share a simple JavaScript code that will untick the default value, unless the lookup column already contains data:

$(document).ready(function () {

    var modalList = $("#cr285_customerlookup_lookupmodal").find(".entity-lookup").find(".entity-grid").eq(0);
    modalList.on("loaded", function () {
        var lookupValue = $("#cr285_customerlookup").val();
        if (!!!lookupValue) {
            var selected = modalList.find("table tbody > tr.selected");
            $(selected).find("td[data-th=Select] > span[role='checkbox']").click()
        }

    });
});

Also worth mentioning that this is not removing the record/row from the table within the modal. It is simply deselecting the record.

I hope this helps with your Power Apps Portals implementation.