The post describes an example of navigating to a HTML web resource (i.e. Tokenisation.html), which is embedded in a Dynamics 365 form
(Note: the Power Apps client API Xrm.Navigation.navigateTo (discussed in this post) navigates to either a table list, table record, HTML web resource or a custom page.)
Walkthrough of the example
a.) Firstly, the user presses the ‘Tokenisation’ button (Figure 1)

b.) Pressing this button calls a JavaScript file Invoice.js. (Figure 2 shows a snippet from this file)

A few things to note about the code displayed in Figure 2:
- The web resource (Tokenisation.html) is registered within Dynamics 365 (Figure 7)
- The data parameter allows data to be passed to the web resource. In this case, the data parameter is a Customer field data type. (This can link to either an Account or a Contact entity.) It’s sent as a query string within the URL (Figure 3)
- target: 1 means that the HTML is launched inline (Figure 5)
- target: 2 means that the HTML is launched as a dialog (Figure 6)
- position: 1 means that the dialog is centered in the middle of the page (Figure 5)
- position: 2 means that the dialog is aligned on the right of the screen (Figure 6)
c.) Xrm.Navigation.navigateTo (Figure 2) executes with following query string (underlined in green) along with Tokenisation.html

d.) Tokenisation.html loads and renders as shown in Figure 4. Note:
- Bootstrap formats the UI. (FluentUI would probably have been a better choice since it’s used natively by the Power Platform)
- Font Awesome generates the spinner and JQuery for the scripting

Altering some settings in the Xrm.Navigation.navigateTo call
e.) Figure 5 is an example of the settings being target: 1 & position: 1 in the Xrm.Navigate.navigateTo call. Figure 6 is an example of the settings being target: 2 & position: 2


Appendix
The developer specifies the ‘Display Name’ for the HTML web resource here (Figure 7)

A code snippet from Tokenisation.html
The code snippet below represents part of the Tokenisation.html. Referring to this code snippet, the function generateToken() (line 32) retrieves the data entered in the ‘Card Tokenisation’ dialog (Figure 4). It also extracts the contact ID (that it, the query string parameter presented in Figure 3 (i.e. ?data=customerid%3d%7b66C762A0-E3D5…) )
Just as an FYI, another aspect of the function generateToken() which hasn’t been discussed in this post, is the Azure function (line 44). Although the code for the Azure function isn’t shown, the function
- Connects to Dynamics 365 / Dataverse to retrieve the merchant details stored in a Dataverse record.
- Makes a httpClient request to the merchant (the request containing the entered credit card details) to generate a payment token
- Then, makes a httpClient request to a Power Automate flow to create a ‘Tokenisation Log’ record in Dataverse
<!DOCTYPE html>
<html>
...
<body>
<div id="ajaxspinner" class="fa fa-spinner fa-spin" style="font-size: 144px;display: none"></div>
...
</div>
<script>
$(document).ready(function () {
$("#createtoken").prop('disabled', true);
$("#createtoken").click(generateToken);
$('#cardname').keyup(function () {
EnableDisableButton();
});
$('#cardnumber').keyup(function () {
EnableDisableButton();
//Adding hyphens to the credit card number
var addHyphens = $(this).val().split("-").join("");
if (addHyphens.length > 0) {
addHyphens = addHyphens.match(new RegExp('.{1,4}', 'g')).join("-");
}
$(this).val(addHyphens);
});
$('#cardexpiry').keyup(function () {
EnableDisableButton();
});
});
function generateToken() {
$('#cardnumber').css({ "border": '#C8C8C8 1px solid' });
var cardName = $('#cardname').val();
var cardNumber = $('#cardnumber').val();
var cardType = $('#cardtype').val();
var cardExpiry = $('#cardexpiry').val();
var customerURI = decodeURIComponent(GetUrlParameter('data'));
var customerId = customerURI.substring(12, 48);
var customerType = customerURI.substring(63, customerURI.length);
var result = validateCardnumber(cardNumber, cardType);
jQuery.ajax({
type: 'GET',
url: 'https://contosofunctions20203302122549.azurewebsites.net/api/TokenGenerator?cardname=' + cardName +
'&cardnumber=' + cardNumber + '&cardexpiry=' + cardExpiry + '&cardtype=' + cardType +
'&customerid=' + customerId + "&customertype=" + customerType,
dataType: 'json',
beforeSend: function () {
$('#ajaxspinner').show();
$('#tokengenerationoutcome').text("");
$("#createtoken").prop('disabled', true); //disable the button
},
complete: function (result) {
},
success: function (result) {
$('#ajaxspinner').hide();
if (result.isOk == false) alert(result);
if (result === 'Token generated - please close this window') {
$('#tokengenerationoutcome').text("Success message: " + result).css({ 'font-weight': 'bold', 'color': 'green' });
$("#createtoken").prop('disabled', true); //disable the button
} else {
$('#tokengenerationoutcome').text("Failure message: " + result).css({ 'font-weight': 'bold', 'color': 'red' });
$("#createtoken").prop('disabled', false); //disable the button
}
},
error: function (request) {
$('#ajaxspinner').hide();
},
});
}
function GetUrlParameter(sParam) {
var sPageURL = window.location.search.substring(1);
var sURLVariables = sPageURL.split('&');
for (var i = 0; i < sURLVariables.length; i++) {
var sParameterName = sURLVariables[i].split('=');
if (sParameterName[0] == sParam) {
return sParameterName[1];
}
}
}
function EnableDisableButton() {
if (($('#cardname').val() == '') || ($('#cardnumber').val() == '') || ($('#cardexpiry').val() == '')) {
$("#createtoken").prop('disabled', true);
} else {
$("#createtoken").prop('disabled', false);
}
}
function validateCardnumber(inputtxt, creditcardtype) {
if (creditcardtype == 'VISA') {
var cardno = /^(?:4[0-9]{12}(?:[0-9]{3})?)$/; //Regex
if (inputtxt.match(cardno)) {
return true;
}
else {
$('#tokengenerationoutcome').text("Failure message: Visa card number is invalid").css({ 'font-weight': 'bold', 'color': 'red' });
$('#cardnumber').css({ "border": '#FF0000 1px solid' });
throw "Visa card number is invalid";
}
}
...
}
</script>
</body>
</html>
Further reading
Pass data to a Dynamics 365 HTML web resource