In this article, we will explore CRUD operations in Dynamics 365 portals using Web API.
We will address the following topics.
- An overview of Power Portal.
- The process of creating a portal.
- Performing CRUD operations in Power Portal using Web API.
What are portals?
Portals are websites that you can customize to give your customers, partners, and employees a tailored experience. Portals are integrated into Dynamics 365 for Customer Engagement so you can display data from the module directly on the portal.
How to create a portal?
1. Login to https://make.powerapps.com/
2. Go to "Apps," then select "New app," and proceed by clicking "OK" for the portal.
3. Enter the necessary portal name and address details, then click on the "Create" button.
It will take a few minutes of time to create the portal.
Perform crud operation in the power portal using web API
Here we go to perform crud operation in the power portal using web API.
4. After creating the Power Portal, go to portal management, click on site settings, and create three active site settings with the same Name and Value as shown in the figure below. Ensure you select your website in the "Web Site" column.
5. Next Navigate to table permission and create contact table permission in the screen below, granting read, create, and delete privileges.
6. Next, we need to create a web role so that only users who have access can perform this operation.
7. After creating the web role, go to its related settings, choose an entity (e.g., select the contact entity), and add users to the role.
8. Next we need to create web templates and add the below completed.
<div class="container" style="margin: 100px">
{% fetchxml contactList %}
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false">
<entity name="contact">
<attribute name="fullname" />
<attribute name="telephone1" />
<attribute name="emailaddress1" />
<attribute name="contactid" />
<attribute name="firstname" />
<order attribute="fullname" descending="false" />
<filter type="and">
<condition attribute="statecode" operator="eq" value="0" />
</filter>
</entity>
</fetch>
{% endfetchxml %}
<div style="float:right">
<button id="createContactNew" class="btn btn-success btn-large" onclick="create();">
<i class="glyphicon glyphicon-plus"></i>Create
</button>
<button id="updateContact" class="btn btn-success btn-large" onclick="update('U')">
<i class="glyphicon glyphicon-inbox"></i>Update
</button>
<button id="deleteContact" value="Delete" class="btn btn-danger btn-large" style="margin-left:20px" onclick="update('D')">
Delete
</button>
<button id="refreshcontact" value="Refresh" class="btn btn-danger btn-large" style="margin-left:20px" onclick="javascript:location.reload(true);">
<i class="glyphicon glyphicon-refresh"></i>Refresh
</button>
</div>
<div id="processingMsg" class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-info-sign"></span>Power Portal Crud Operation Using Web API
</div>
<table id="tblData" class="table" style="border:1px solid">
<thead class="thead-dark">
<tr class="table-heading">
<th><input type="checkbox" id="checkedAll" style="margin-left:30px" /></th>
<th>First Name</th>
<th>Email</th>
<th>Business Phone</th>
</tr>
</thead>
<tbody>
{% for result in contactList.results.entities %}
{% assign contactids = result.contactid %}
<tr>
<td><input type="checkbox" id="{{ result.contactid }}" class="contactIDs" style="margin-left:30px" onchange="pushArrayCheckBox(this);" /></td>
<td><input type="text" id="txtfullName|{{result.contactid}}" contactid="{{result.contactid}}" value="{{ result.firstname }}" onchange="pushArray(this);"></td>
<td>{{ result["emailaddress1"] }}</td>
<td><input type="number" id="txtBusinessPhone|{{result.contactid}}" contactid="{{result.contactid}}" value="{{ result.telephone1 }}" pattern="\d*" title="Please enter Numbers only..." onchange="pushArray(this);"></td>
</tr>
<tr class="no-records" style="display: none;">
<td colspan='6'>No Record Found</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<script>
(function(webapi, $) {
function safeAjax(ajaxOptions) {
var deferredAjax = $.Deferred();
shell.getTokenDeferred().done(function(token) {
if (!ajaxOptions.headers) {
$.extend(ajaxOptions, {
headers: {
"__RequestVerificationToken": token
}
});
} else {
ajaxOptions.headers["__RequestVerificationToken"] = token;
}
$.ajax(ajaxOptions).done(function(data, textStatus, jqXHR) {
validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve);
}).fail(deferredAjax.reject);
}).fail(function() {
deferredAjax.rejectWith(this, arguments);
});
return deferredAjax.promise();
}
webapi.safeAjax = safeAjax;
})(window.webapi = window.webapi || {}, jQuery)
var globalArray = [];
function pushArrayData(currentObject) {
var str = currentObject.id;
var res = str.split("|");
var contId = res[1];
var checkbox = document.getElementById(contId).checked;
var fullname = document.getElementById("txtfullName|" + contId).value;
var phonenumber = document.getElementById("txtBusinessPhone|" + contId).value;
let objIndex = globalArray.findIndex((obj => obj.id == contId));
if (objIndex == -1) {
globalArray.push({
id: contId,
fullname: fullname,
phone: phonenumber,
checkboxval: checkbox
})
} else {
globalArray[objIndex].fullname = fullname;
globalArray[objIndex].phone = phonenumber;
globalArray[objIndex].checkboxval = checkbox;
}
}
function pushArrayCheckBox(currentObject) {
var contId = currentObject.id;
var checkbox = document.getElementById(contId).checked;
var fullname = document.getElementById("txtfullName|" + contId).value;
var phonenumber = document.getElementById("txtBusinessPhone|" + contId).value;
let objIndex = globalArray.findIndex((obj => obj.id == contId));
if (objIndex == -1) {
globalArray.push({
id: contId,
fullname: fullname,
phone: phonenumber,
checkboxval: checkbox
})
} else {
globalArray[objIndex].fullname = fullname;
globalArray[objIndex].phone = phonenumber;
globalArray[objIndex].checkboxval = checkbox;
}
}
function updateRecord(flag) {
var i;
for (i = 0; i < globalArray.length; i++) { //update checked row changes
alert(globalArray[i].fullname + "-" + globalArray[i].phone + "-" + globalArray[i].checkboxval);
if (globalArray[i].checkboxval == 1) //true
{
document.getElementById("processingMsg").innerHTML = "Processing....";
try {
let value = {
"firstname": globalArray[i].fullname,
"telephone1": globalArray[i].phone
};
if (flag == "U") {
webapi.safeAjax({
type: "PATCH",
url: "/_api/contacts(" + globalArray[i].id + ")",
contentType: "application/json",
data: JSON.stringify(value),
success: function(res) {
document.getElementById("processingMsg").innerHTML = "Records updated successfully.";
}
});
} else if (flag == "D") {
webapi.safeAjax({
type: "DELETE",
url: "/_api/contacts(" + globalArray[i].id + ")",
contentType: "application/json",
success: function(res) {
document.getElementById("processingMsg").innerHTML = "Records deleted successfully. Refresh the page.";
}
});
}
} catch (e) {
alert(e.message);
}
}
}
}
// To create new contact
function createRecord() {
var fname = prompt("Please enter your first name", "First Name");
var lname = prompt("Please enter your last name", "Last Name");
var email = prompt("Please enter your email", "Email");
var phone = prompt("Please enter your phone number", "Phone Number");
var recordObj = {
"firstname": fname,
"lastname": lname,
"emailaddress1": email,
"telephone1": phone
};
document.getElementById("processingMsg").innerHTML = "Creating record...";
webapi.safeAjax({
type: "POST",
url: "/_api/contacts",
contentType: "application/json",
data: JSON.stringify(recordObj),
success: function(res, status, xhr) {
document.getElementById("processingMsg").innerHTML = "Records created successfully. Refresh the page. ID:" + xhr.getResponseHeader("entityid");
}
});
}
$(document).ready(function() {
$('#checkedAll').on('click', function() {
if (this.checked) {
$('.contactIDs').each(function() {
this.checked = true;
$(this).parent().parent().css({
"color": "red",
"background-color": "#faffd6"
});
});
} else {
$('.contactIDs').each(function() {
this.checked = false;
$(this).parent().parent().css({
"color": "black",
"background-color": "#ffffff"
});
});
}
});
$('.contactIDs').on('click', function() {
if ($('.contactIDs:checked').length == $('.contactIDs').length) {
$('#checkedAll').prop('checked', true);
$('.contactIDs').each(function() {
$(this).parent().parent().css({
"color": "red",
"background-color": "#faffd6"
});
});
$(this).parent().parent().css({
"color": "black",
"background-color": "#ffffff"
});
} else {
$('#checkedAll').prop('checked', false);
$(this).parent().parent().css({
"color": "black",
"background-color": "#ffffff"
});
}
});
});
</script>
9. Next we need to create a page template to display web content, navigate to the page template, and click on New and New.
10. Complete the required fields, specifying the web template in the "Type" field and choosing your created template in the "Web Template" field. For the table name, select the entity, and then click "Save."
11. Navigate to https://make.powerapps.com/ click on edit portal and create a new sub-page, refer below screen.
12. Provide the necessary information in the web component and choose your template.