Let’s say you have a Dataverse record that you want to do some things to post creation, for example, maybe you have special requirements for generating a value for the Primary Name column or need to add records to another Dataverse table, and so on.
That begs the question, how would you prevent the user from making changes to the Dataverse record before it was ready?
I created a Table in Dataverse called Item
, with the following additional fields:
Description
– Text
State
– Internal choices for Preparing, Error and Ready
State Reason
– Text with an explanation of the State, if needed, for example, what if one of the steps in the things I wanted to do was unable to complete, this is where I would put that message.
State
defaults to Preparing.
I created a Flow called Item Row Added
to mimic doing some work whenever a new record was added to the Item
table.
I created a Model-Driven App called Item App
and added support for the Item
table.
I add the Description
, State
and State Reason
fields to the Information Main Form. I set State
and State Reason
to Read-only.
Let’s look at the requirements again.
If the record is new, allow the User to Save the changes.
If the record is an existing record, and is in any other State than Preparing, allow the User to Save the changes.
To make this work I was going to have to use JavaScript, so I created a file called ItemForm.js
with thhe code found at https://gist.github.com/mattruma/02d9b9f3c82c61ac3911bf36ab2f4399#file-itemwithstateform-js.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
// https://learn.microsoft.com/en-us/power-apps/developer/model-driven-apps/clientapi/walkthrough-write-your-first-client-script var ItemForm = window.ItemForm || {}; (function () { console.log("ItemForm - Version", "2023.04.18.06"); const preparingState = 968050000; // This is the numeric value assigned by Dataverse for my choice const preparingMessage = "This record is still being prepared. You won't be able to make any changes. Please try again in a few minutes."; this.formOnLoad = function (executionContext) { var formContext = executionContext.getFormContext(); if (!isNewRecord(formContext) && isPreparingRecord(formContext)) { Xrm.Navigation.openAlertDialog({ text: preparingMessage }); formContext.ui.setFormNotification(preparingMessage, "INFO", "ItemWithStateForm"); } } this.formOnSave = function (executionContext) { var formContext = executionContext.getFormContext(); if (!isNewRecord(formContext) && isPreparingRecord(formContext)) { executionContext.getEventArgs().preventDefault(); Xrm.Navigation.openAlertDialog({ text: preparingMessage }); } } function isNewRecord(formContext) { var entityReference = formContext.data.entity.getEntityReference(); return !entityReference.id; } function isPreparingRecord(formContext) { var state = formContext.data.entity.attributes.get("maruma_state").getValue(); if (state == preparingState) { return true; } return false; } }).call(ItemForm); |
Note, my publisher prefix is maruma
, so if you tried this, would be whatever your publisher prefix is for accessing fields in the Item
table.
Form the Solution, I uploaded the JavaScript file as a Web Resource by clicking on New and then Web Resource.
With the JavaScript file uploaded time to wire up the JavaScript to the Information Main Form.
From the Solution, I click on the three dots next to my Model-Driven App and click Edit.
From the Sidebar Menu I click Pages and then Item forms.
I then hover over the Information Main Form and click the Pencil icon.
Time to wire up the events.
I click the Events tab on the far right and then click Event Handler for On Save.
I set Library to my JavaScript file which I uploaded as a Web Resource.
I set Function to my ItemForm.formOnSave
function in my JavaScript file and check Pass execution context as first parameter.
Repeat the same for On Load using the ItemForm.formOnLoad
function.
Click Save and publish when complete.
Click Back and then click Publish to publish the application.
Click Play.
Now when I run my app and look at a record that has a State of Preparing a notification and an alert are displayed.
Same dialog will show if the User clicks Save or Save and Close.
There we go!
Not the most “low-code” solution, but it gets the job done!
Discover more from Matt Ruma
Subscribe to get the latest posts sent to your email.