Opening a Canvas Apps from Ribbon Button in Dynamics 365
Currently there is no straight forward way to open a canvas apps from the ribbon button unlike the custom page that can be opened using the Xrm.Navigation.navigateTo(pageInput,navigationOptions).then(successCallback,errorCallback);
Refer : navigateTo (Client API reference)
However the navigateTo
client api allows us to call a HTML webresource, which is exactly how we can open/launch the canvas apps from the ribbon button.
Creating the JavaScript webresource to call the HTML webresource*.*
In the below code, we are passing the primaryControl, canvas apps AppId and the HTML webresource name as parameters from the ribbon work bench.
function openCanvasApp(executionContext, appId, webresource) {
var recordId = executionContext.data.entity.getId();
var iframeSrc = encodeURIComponent(`https://apps.powerapps.com/play/${appId}?source=iframe&recordId=${recordId}`);
var pageInput = {
pageType: "webresource",
webresourceName: webresource,
data: iframeSrc // Passing iframeSrc as data parameter
};
var navigationOptions = {
target: 2,
position: 2,//open as a side pane
width: { value: 500, unit: "px" }
};
// Using navigateTo Client API
Xrm.Navigation.navigateTo(pageInput, navigationOptions).then(
function success() {
// Run code on success
},
function error() {
// Handle errors
}
);
}
Steps to configure the parameters in Ribbon Workbench :
1. Use the ribbon workbench and create a button, add the label, icon etc. and create a command and associate it to the ribbon button, in the command set the below properties for the custom JavaScript action
Primary control : Is the recordId of the entity where the ribbon button is added
The first string parameter is the canvas apps AppId can be found in the details page of the canvas apps.
The second string parameter is the HTML webresource name
HTML Webresource
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title> <!-- Empty title to remove the header -->
<style>
body, html {
margin: 0;
padding: 0;
overflow: hidden;
}
iframe {
width: 100%;
height: 100%;
border: none;
}
</style>
</head>
<body>
<script>
// Extract the iframeSrc parameter from the Xrm navigation data
function getDataParameter(name) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(name);
}
const iframeSrc = getDataParameter('data');
if (iframeSrc) {
const recordId = decodeURIComponent(iframeSrc).split('&recordId=')[1];
const fullUrlWithRecordId = decodeURIComponent(window.location.href);
console.log('Full URL with Record ID:', fullUrlWithRecordId);
document.write('<iframe src="' + decodeURIComponent(iframeSrc) + '" allow="geolocation; microphone; camera"></iframe>');
} else {
console.error('iframeSrc data parameter is missing');
}
</script>
</body>
</html>
getDataParameter() is the function that is used to extract the
value
of parameter from the URL query string, it parses the query string part of the url using thewindow.location.search
decodeURIComponent()
decodes the value in the Iframesrc which is the URLSplits the decoded string using the '&' as a separator and extracts the recordId=. this is basically the recordId parameter.
This way we do not have to hardcode the canvas apps url in the iframe, rather pass them as parameter from the ribbon workbench and access them.
This above code will remain same for opening canvas apps, except the first string parameter (AppId)passed from the ribbon workbench can change from one canvas apps to other.