Custom HTML forms in Power Pages
One of the features of Power Pages is the ability to use a model-driven app Dataverse form as a foundation to build create, edit, and read-only forms on Power Pages.
The form designer in the Data workspace is actually the same designer used for model-driven apps. what you see is a model-driven app version and not a Power Pages version, or rather a ‘what you see is a model-driven form and what you will get is a Power Pages form’ (WYSIAMDFAWYWGIAPPF) Doesn’t quite roll off the tongue, does it?
The other aspect is if you want to customize or configure the form beyond the 2 or 3 column layout, your options are limited.
Using these technologies, you can create a fully customized HTML form that you can use to read, write, and update Microsoft Dataverse information, and provide you with the full flexibility to modify and configure the form as you see fit, without having to work with the model-driven app constraints.
This pro-code approach may help with scenarios that have unique requirements for adding information to Dataverse.
The steps to build a form for creating new records break down like this:
Create a custom web template
Add an HTML form to capture the data
Configure site settings for table and columns
Create code to the do the following:
On the submit action of the HTML form, take the data and create an object
Submit the object to Dataverse using the Power Pages WebAPI
Add some CSS to make the form look nice
Creating a custom web template
To create a custom web template, page template and web page, check out my recent post using Visual Studio Code or check out the official documentation on web templates.
Creating the HTML form to capture data
For this example, I will create a custom web template using Visual Studio Code. See my recent post/video on creating a webpage using Visual Studio.
The first thing is to create a simple HTML form, using the logical names of the Dataverse table fields that I want to either create or update, they don’t need to match, but it does help get things straight.
The following is a sample HTML form used to create new sessions for a conference.
<form id="myForm">
<label for="docs_sessionname">Session Name:</label>
<input type="text" id="docs_sessionname" name="docs_sessionname" required><br>
<label for="docs_sessiondescription">Session Description:</label>
<textarea id="docs_sessiondescription" name="docs_sessiondescription" required></textarea><br>
<label for="docs_sessiondateandtime">Session Date and Time:</label>
<input type="datetime-local" id="docs_sessiondateandtime" name="docs_sessiondateandtime" required><br>
<label for="docs_duration">Duration (minutes):</label>
<input type="number" id="docs_duration" name="docs_duration" required><br>
<input type="submit" value="Submit">
</form>
<label for="docs_sessionname">Session Name:</label>
<input type="text" id="docs_sessionname" name="docs_sessionname" required><br>
<label for="docs_sessiondescription">Session Description:</label>
<textarea id="docs_sessiondescription" name="docs_sessiondescription" required></textarea><br>
<label for="docs_sessiondateandtime">Session Date and Time:</label>
<input type="datetime-local" id="docs_sessiondateandtime" name="docs_sessiondateandtime" required><br>
<label for="docs_duration">Duration (minutes):</label>
<input type="number" id="docs_duration" name="docs_duration" required><br>
<input type="submit" value="Submit">
</form>
Configure site settings to use Web API.
As per the Microsoft documentation, you will need to add appropriate site settings to allow the Web API to create new records in Dataverse. You will also need to make sure the correct table permissions are also configured. In my example, I choose * for all fields, in a production setting, only choose the fields that you will need in the WebAPI calls as well as limiting access to data using table permissions.
Create code to create records.
Now that we have our form, how can we get the information to Microsoft Dataverse? This is where the Power Pages WebAPI comes in handy.
You will need to add the helper code (AJAX wrapper) to your site and reference it from your web template (the full source code shows this).
Here is some Power Pages WebAPI code that will take the data added to the form and create a new record in Dataverse when the form submit action is called:
$('#myForm').submit(function(event) {
event.preventDefault(); // Prevent the default form submission
// Create a new record object from form data
var record = {};
record.docs_sessionname = $('#docs_sessionname').val(); // Text
record.docs_sessiondescription = $('#docs_sessiondescription').val(); // Multiline Text
record.docs_sessiondateandtime = $('#docs_sessiondateandtime').val(); // Date Time
record.docs_duration = parseInt($('#docs_duration').val()); // Whole Number
// Call the WebAPI helper function to create the record
webapi.safeAjax({
type: "POST",
contentType: "application/json",
url: "/_api/docs_sessions",
data: JSON.stringify(record),
success: function (data, textStatus, xhr) {
var newId = xhr.getResponseHeader("entityid");
console.log(newId);
// Reset the form after successful submission
$('#myForm')[0].reset();
alert("Record added successfully."); //Add alerts because they are so elegant :)
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr);
}
});
}
event.preventDefault(); // Prevent the default form submission
// Create a new record object from form data
var record = {};
record.docs_sessionname = $('#docs_sessionname').val(); // Text
record.docs_sessiondescription = $('#docs_sessiondescription').val(); // Multiline Text
record.docs_sessiondateandtime = $('#docs_sessiondateandtime').val(); // Date Time
record.docs_duration = parseInt($('#docs_duration').val()); // Whole Number
// Call the WebAPI helper function to create the record
webapi.safeAjax({
type: "POST",
contentType: "application/json",
url: "/_api/docs_sessions",
data: JSON.stringify(record),
success: function (data, textStatus, xhr) {
var newId = xhr.getResponseHeader("entityid");
console.log(newId);
// Reset the form after successful submission
$('#myForm')[0].reset();
alert("Record added successfully."); //Add alerts because they are so elegant :)
},
error: function (xhr, textStatus, errorThrown) {
console.log(xhr);
}
});
}
A touch of CSS to make the form look nice
The style code should be added (ideally as a custom CSS file, but I embedded on the web template purely out of laziness.)
<style>
/* Adjust the styles as needed */
form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #042B3C;
border-radius: 5px;
background-color: #FEFEFE;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #042B3C;
}
input[type="text"],
textarea,
input[type="datetime-local"],
input[type="number"] {
width: 100%;
padding: 8px;
border: 1px solid #042B3C;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 10px;
background-color: #FEFEFE;
color: #042B3C;
}
input[type="submit"] {
background-color: #76BC21;
color: #FEFEFE;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
input[type="submit"]:hover {
background-color: #FF4712;
}
</style>
/* Adjust the styles as needed */
form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #042B3C;
border-radius: 5px;
background-color: #FEFEFE;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
color: #042B3C;
}
input[type="text"],
textarea,
input[type="datetime-local"],
input[type="number"] {
width: 100%;
padding: 8px;
border: 1px solid #042B3C;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 10px;
background-color: #FEFEFE;
color: #042B3C;
}
input[type="submit"] {
background-color: #76BC21;
color: #FEFEFE;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: bold;
}
input[type="submit"]:hover {
background-color: #FF4712;
}
</style>
The form should appear on the website and users with the appropriate permissions should be able to add records