Power Pages: Prefill fields with data form the user profile

Microsoft Power Platform provides powerful tools for creating web portals, and Power Pages is one of them. In this blog post, we’ll explore how to enhance the user experience by pre-filling order forms on your portal using custom fields. Specifically, we’ll focus on pre-populating the order form with data from the user’s profile page.

Imagine you have a Power Pages website with an order form. Users need to fill out details such as their city and country and other relevant information. To streamline this process, we’ll leverage custom fields you’ve added to the user’s profile page. When a user accesses the order form, we’ll automatically populate these fields based on their profile information.

Adding fields to the Profile

  • Add the required fields to the Contact and Order table in Dataverse
  • For example, a text field called City and a lookup field called Country.
  • Add the fields to the form Profile Web Form, which is the default form used in the Power Pages profile page.
  • Open the Power Pages website to see if the changes are visible and fill them.

JavaScript to prefile the columns on a order

  • Open the Portal Management of your Power Pages website.
  • Open the element where you need to prefill the fields. In my case it’s the Order Information Web Form Step that is part of the Create Order Web form.
  • On the tab Form Options (this can be different per element) and navigate down to the Custom JavaScript input box.
  • Add the following code and change the following if needed.
$(document).ready(function() {

    //Get the profile county ID and Name data
    var CountryGUID = "{{ user.abc_country.id }}";
    var CountryName = "{{ user.abc_country.name }}";    
  
    //Get the City from the users profile (contact table)
    var City = "{{ user.abc_city }}";
  
    //set the text input element city with the profile field City
    document.getElementById("city").value = City;

    //set the lookup input element with the profile field Country
    //Set the name of the lookup field
    $("#abc_country_name").attr("value",CountryName);
    //Set the GUID of the lookup field
    $("#abc_country").attr("value", CountryGUID);
    //Set the logical name of the lookup table
    $("#abc_country_entityname").attr("value","abc_country");
});
  • Open the page in a web browser and use the web developers tools (f12) to find the id of the city field.
  • Update the document.get ElementById if required.
  • Do the same thing for the #abc_country_name, #abc_country and #abc_country_entityname.
  • Update the $(“”).attr where required.
  • If you are using different field names make sure to update the field names or add them to JavaScript.
  • {{ user.[fieldname] }} will return the value of that field.
  • {{ user.[fieldname].id }} will return the id of the selected value of a lookup field.
  • {{ user.[fieldname].name }} will return the name of the selected value of a lookup fields.
  • Save the changes and your fields will now be filled automatically.

Enhancing Dynamics 365 Supply Chain Management Customer Portal: Adding Editing and Deleting Functionality to Orders

Within the Dynamics 365 ecosystem, the Customer Portal serves as a gateway for clients to interact with your organization and order products. While the default template for Power Pages/Portal facilitates order creation and product management, it falls short when it comes to allowing users to edit or delete existing orders and products.

In this blog post, we embark on a journey to enhance the functionality of the Dynamics 365 Supply Chain Management Customer Portal. We’ll focus specifically on empowering users with the ability to edit and delete orders and products, providing them with greater control over their transactions.

By default, there is no option to go to orders that are not submitted, so I added the a page to see the draft orders.

Besides adding the draft order view, I renamed other tiles and a link to the create order page.

Order editing

I will assume that you already have a Power Pages setup with the Supply Chain Management Customer Portal template and that you know how to add a new page named Draft Orders with a view and how to make a tile. I will go straight into how to add the capability to edit an order and its products.

  • Add a new page called Update Order to the Portal.
  • Open the Draft Orders page and select the Edit Record option under List settings – Actions.
  • Select the newly created page Update order and give it the name Update Order.
  • The Target type is Webpage.
  • Then open the Portal Management tool to create the Web Form. A web form is a form with multiple steps.
  • Open the already existing Web Form called Create Order.
  • Open a new tab and create a new Web Form called Update Orders.
  • Setup the Update orders Web form exactly the same as the Create order Web form.
  • Under Web Pages add the existing page called Update Order.
  • Open the Update Order page to make sure the Web Form property is set to the newly created Update Orders web form and the Publishing State is Published.
  • Reopen the Web Form and open the Web Form Steps tabs.
  • Create four new web form steps equal to the steps in the create order web form.
  • Some of the settings cannot be set in the user interface. You will have to open the table adx_webformstep in Dataverse to make sure all the settings are the same.
  • Now that the steps are the same, we are going to make the following changes to them.
  • Open the step Items and set under Form Definitions the Mode to Insert.
  • Reconfigure the Source type to Results From Previous Step
  • Reconfigure the Entity Source Step to Order Information.
  • Open the tab Metadata under and create a new Subgrid
  • Select the Type Subgrid
  • Selected the salesoderdetailsGrid
  • In the Grid Configuration we will add the buttons for Edit, Delete and Add item.
  • Click on Create in the View Actions section to create the following action.
  • Create the delete action in the Item Actions section.
  • Create the view details action in the Item Actions sections.
  • Open the step Order Information and set under Form Definitions the Mode to Edit.
  • Reconfigure the Source type is Query String
  • Reconfigure the Primary Key to ID, if it changed.
  • Reconfigure the Name to Order (Salesorderid), if it changed.
  • You have now created the web form for your users to enjoy!

Add Power Fx buttons to model-driven apps

Model-driven apps, a fundamental component of the Power Apps suite, provide a robust framework for designing data-driven solutions. While they offer a wealth of functionality out of the box, adding customized actions and automations can greatly enhance the user experience and boost operational efficiency. This is where low-code Power Fx buttons come into play, providing a simple yet effective way to empower users to take control of their apps and automate routine tasks.

In this blog post, we will delve into the world of low-code development and explore how you can leverage Power Fx buttons to supercharge your model-driven apps. We’ll walk you through the process of adding a button that when pressed will save data in Dataverse.

Creating a Power Fx Button (command bar button)

  • Open your Model-driven app in edit modus.
  • Select … of the table (entity) where you need to add the button.
  • Click on Edit or Edit in new tab under Edit command bar.
  • Select the command bar that where the button needs to be added, in my case that is the Main form.
  • Click on Edit and the command bar will be loaded.
  • Click on New followed by Command to add a new button.
  • Change the label (name) of the button and place (drag) it to the correct location on the command bar.
  • If required select an Icon, selecting an icon help the user with recognizing the button and its function.
  • With the help of Power Fx code we can add when the button will be displayed (visible). For example; Only show the button when the the color field has the value Green.
  • Select the Show on condition from formula on the Visibility property.
  • Click on the Open formula bar, that appears below the property.
  • Add your Power Fx command that dictates when the button needs to be displayed.
If(Self.Selected.Item.color = "Green", true, false)
  • Click on Open formula bar under the Action property to add the Power Fx code that needs to be executed when the button is pressed.
  • Add your Power Fx command that needs to be executed, in my example it set the color field value to Purple.
Patch(Tasks,Self.Selected.Item, {color:"Purple"});
  • Click on Save and Publish when the button is ready.
  • Play the Model-driven app to see if the button is working correctly.

Retrieve Dataverse records with JavaScript

When validations or manipulations in a model-driven app are too complex for a business rule you can use JavaScript instead. With JavaScript you can use the Dynamics API to gather information and/or update records. JavaScript only runs on the interface; this means that the validation or manipulation only happen when a user is interacting with the model-driven app.

retrieveRecord

With retrieveRecord you can retrieve a records form a table if you know the ID.

Xrm.WebApi.retrieveRecord("account", "a8a19cdd-88df-e311-b8e5-6c3be5a8b200", "?$select=name,revenue")

Xrm.WebApi.retrieveRecord("TABLE", "ID", "?$select=COLUMN,COLUMN")

In this example a record from the table accounts is retrieved and the columns name and revenue are returned. If it was successful the results are displayed in the console, if an error occurred then the error message is displayed in the console.

Xrm.WebApi.retrieveRecord("account", "a8a19cdd-88df-e311-b8e5-6c3be5a8b200", "?$select=name,revenue").then(
    function success(result) {
        console.log("Retrieved values: Name: " + result.name + ", Revenue: " + result.revenue);
        // perform operations on record retrieval
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

retrieveMultipleRecords

With retrieveMultipleRecords you can retrieve multiple records from a table based on a filtering.

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name,primarycontactid&$filter=primarycontactid eq a0dbf27c-8efb-e511-80d2-00155db07c77")

Xrm.WebApi.retrieveMultipleRecords("[TABLE]", "?$select=[COLUMN],[COLUMN]&$filter=[COLUMN] eq ID")

In this example three records from the table accounts are retrieved and the columns name is returned. If it was successful the results are displayed in the console, if an error occurred then the error message is displayed in the console.

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name", 3).then(
    function success(result) {
        for (var i = 0; i < result.entities.length; i++) {
            console.log(result.entities[i]);
        }
        console.log("Next page link: " + result.nextLink);
        // perform additional operations on retrieved records
    },
    function (error) {
        console.log(error.message);
        // handle error conditions
    }
);

Expand query to get related records

With the $expand options we can retrieve related records of the record that was returned, this works for both retrieveRecord and retrieveMultipleRecords. Expand uses navigation columns (relationship/lookup) to retrieve the related records.

Xrm.WebApi.retrieveRecord("account", "a8a19cdd-88df-e311-b8e5-6c3be5a8b200", "?$select=name&$expand=primarycontactid($select=contactid,fullname)")
Xrm.WebApi.retrieveRecord("[TABLE]", "ID", "?$select=[COLUMN]&$expand=[NAVIGATION COLUMN]($select=[COLUMN],[COLUMN])")

Xrm.WebApi.retrieveMultipleRecords("account", "?$select=name&$top=3&$expand=primarycontactid($select=contactid,fullname)", 3)
Xrm.WebApi.retrieveMultipleRecords("[TABLE]", "?$select=[COLUMN]&$top=3&$expand=[NAVIGATION COLUMN]($select=[COLUMN],[COLUMN])", 3)

Asynchronous function to wait on the return

When using retrieveMultipleRecords you might need to use an asynchronous function. The function needs to wait on retrieveMultipleRecords to return the values before continuing with the function. You do this by making two async functions, one with the main logic and the second one which retrieves the records.

async function xseption(formContext) {
    var xseptions = await getXseptions(companyProfileId);
    //Do something with the return
}
async function getXseptions(guid) {
    var query = "?$select=rc_categorytypeid,rc_xseptionsid&$filter=_rc_related_companyprofile_value eq " + guid + "&$expand=rc_categorytypeid($select=rc_value)";
    var result = await Xrm.WebApi.retrieveMultipleRecords("rc_xseptions", query);

    return result;
}

Embed a canvas app in a model-driven app

Did you know that you can embed (add) a canvas app in a model-driven app? With the embedded canvas app, you can fully use the power of the canvas app inside a model-driven app. In my project I used it to provide the user with the capability to search an Oracle database and select a specific company.

It is very easy to add a canvas app, but I recommend to use it only when no other options are viable. The reason for this is that the embedded canvas app needs to be reconnected every time you transfer the solution form one environment to another.

Embed the canvas app

  • Create / add a canvas app in the same environment as the model-driven app.
  • Open the form of the entity where the canvas app needs to be embedded.
  • Click on +Component and select the Canvas app.
  • Fill in the App ID Static value with the unique ID of the canvas app and click on Done.
  • You can find the App ID by right clicking on an app and clicking on Details.

Solution deployments

The canvas app is now part of the model-driven app and needs to be in the same solution. When you transfer the solution from the development environment to the test environment, you will need to update the model-driven form manually. The reason for this is that the model-driven app is still connected to the canvas app on development. You will need to change the reference / GUID to the canvass app on production. And do not forget to share the canvas app with the users.