An image with a set of 9 buttons .

Enabling Completed Tasks to be reopened in Dynamics 365 – Model Driven App Forms

Aaron Dulai, who is part of the Microsoft Power Platform Development Team at iThink 365 had an interesting challenge to work through for a customer. This is his first blog post and he describes what he did.

A Model Driven Application contains a table named “Tasks” which is automatically created out of the box. These tasks contain a button on its form that says, ‘Mark as completed’ when clicked, the task becomes read-only, and no user can change the tasks information without going directly to the table.

The challenge here is to create a button that changes the ‘ActivityStatus’ field from completed to open to allow modification to the task. To make it more robust and secure, a security feature will be added that allows only people with certain rights to be able to access this button. Once the button is clicked, the task will automatically refresh so the user can see the new state rather than manually hitting refresh. 

For this specific scenario, a custom security role for admins will only be allowed to set these tasks back to open and make changes.

The final solution we wanted to achieve something like.

An animated gif showing the process of reopening a completed task via a custom button.
Reopening a completed task

Creating The JavaScript File

The JavaScript file will be used in the library section of the command (button) that we are creating, to make the JavaScript file, use an external source such as an IDE, for this scenario we used VS Code. 

To start writing the JavaScript code, it is a good idea to understand the basics such as how to work with functions and variables, to find out more visit: https://javascript.info/function-basics

Create the initial variable and declare it as a global variable, create a function that calls the button object, and make sure the object name is identical to the command (button) name on the Model Driven Application. 

Create variables to hold the Task’s entityId and entityName. 

Another variable is needed to hold the data of the ‘Activity status’ field (open, closed, cancelled). Remember to use the logical name found on the table itself. There will be 2 types of data we will be holding, one to match the correspondent activity status that we will be changing the task to, “0” is the value for an “Open” status. The other will hold the activity of the CRM entity type for the name “statuscode”, in this scenario, we will be setting that to “3” as represents “In Progress”.

For more information on the Dynamics CRM EntityType for Task, please see: https://learn.microsoft.com/en-us/power-apps/developer/data-platform/webapi/reference/task?view=dataverse-latest

Example code:

var i365DynamicsApplication = window.i365DynamicsApplication || {};

(function () {

    this.reopenCompletedTask = function (primaryControl) {

        var formContext       = primaryControl;

        var entityId = formContext.data.entity.getId();

        var entityName = formContext.data.entity.getEntityName();  

        var data = {

            "statecode":0,

            "statuscode": 3

        };

Now, it is time to use ‘updateRecord’ to update the task’s activity status with the data variable we are using to store the statecode and statuscode.

To capture what is happening and debug using ‘Console’ on the web browser once we use this button, use ‘console.log’ to write the successes and errors. This will help to understand where the error is if an error occurs in the execution of the script. Finally, we want to refresh the screen automatically so that the user knows the button has done what it should.

Example code:

Xrm.WebApi.updateRecord(entityName, entityId, data).then(

            function success(result) {

                console.log("Task updated", entityId);

                formContext.data.entity.refresh();

                formContext.data.refresh(false).then((result) => {

                    console.log("Task form refreshed");

                }, (error) => {

                    console.log("Task form refresh failed", error);

                });

                // perform operations on record update

            },

            function (error) {

                console.log(error.message);

                // handle error conditions

            }

        );

    };

}).call(i365DynamicsApplication);

task EntityType (Microsoft.Dynamics.CRM)

learn.microsoft.com

Generic activity representing work needed to be done.

Functions

javascript.info

Creating The Command (Button)

Screenshot of the command bar in Dynamics 365 being edited for the entity task.

A button is used to set the ‘ActivityStatus’ from completed to open. To create this, the Model Driven Application must be in ‘Edit’ mode. Once you are in edit mode, head over to the entity you will need to create the button in, for this scenario, we are using the ‘Tasks’ entity. Edit the command bar and select ‘Main form’ which will bring a screen with loads of buttons. click ‘New command’ and fill in the specifications of the button such as the name, a description, and an icon if needed. 

To find out more information on how to create a new button, please see: https://learn.microsoft.com/en-us/power-apps/maker/model-driven-apps/use-command-designer

Once the button is created it is time to add the JavaScript file to the library. Select ‘Add Library’ followed by ‘New Web Source’. This will then let you add the JS file to the list of libraries. Once you have added the file, select the file from the list of libraries.

Customize the command bar – Power Apps

learn.microsoft.com

Use the command designer to customize the command bar.

Hiding The Button Depending on Permissions and Activity Status

To change the visibility of the button, head to the ‘Visibility’ section on the edit mode for the command (Button). Use the formula bar which uses Power FX to set the visibility so only people with specific access can view the button. This scenario requires users with delete permissions to be able to re-open the task.

This clause enables that behaviour

RecordInfo(Self.Selected.Item, RecordInfo.DeletePermission)

Our next criteria is to allow the button to appear only if the task is closed, it is pointless having it appear if the task is still open and could confuse the users. To add this, we use the “&&” clause followed by a check to see if the status code matches “.completed”. You can use IntelliSense to figure out what the options are for the activity status.

The final PowerFX is:

RecordInfo(Self.Selected.Item, RecordInfo.DeletePermission) && Self.Selected.Item.'Activity Status' = 'Activity Status (Tasks)'.Completed

Now that this is all set up, it is time to save & publish then play. A new tab that opens once you click play. Now you can test out your button. We use the browser tools to check that things are behaving themselves and access them via Microsoft Edge using F12.

Conclusion

In this article we showed you how you can add a button to reopen a completed task in Dynamics 365 or Model Driven Apps. We explained how to restrict the functionality to only being available to certain users and also for it to only be enabled when a task was completed.