Resco Inspections on Power Platform
Traditionally, end users consume questionnaires in Resco mobile apps. Since Release 16.1 (summer 2023), questionnaires can also be used in various components of the Microsoft Power Platform: Power Apps and Power Pages.
As your backend server, use Microsoft Dataverse - with or without extra Dynamics features.
Prerequisites
Here's a high-level overview of steps to prepare your environment:
- Go to https://make.powerapps.com/.
- Install the Woodford managed solution. (How?) The minimum supported version is 16.1.
- Use the Questionnaire Designer to create and publish at least one questionnaire.
Why Woodford
In this scenario, the Woodford tool is not used. So why is the Woodford solution needed? It includes several other components necessary for inspections:
- Custom tables, e.g., questionnaire
- Questionnaire Designer, the backend tool for designing and managing questionnaire templates
- Several standard views for the questionnaire table, as well as a custom form - the Questionnaire Player web resource. These can be used on the Power Platform.
Power Apps
The Questionnaire table can be easily integrated into your Power Apps with only a few clicks. Treat Questionnaire just like a standard Dataverse table, with the Questionnaire player replacing the standard table form.
Create a model-driven app
- Go to https://make.powerapps.com/ (Power Apps home).
- Ensure you are in the environment with the Woodford solution installed.
- Optionally, go to (or create) a solution to keep your work organized. (Solutions are particularly useful if you want to transfer all your customizations to a different environment.)
- Edit a model-driven app, or create a new one.
- Click Add page and select Dataverse table, then click Next.
- Select the "Questionnaire" table and click Add.
- Save all changes, publish the app, then click Play to run it.
Read more about the questionnaire list, form, and player.
How to add Forms+ to the form of the Model Driven Apps
The Appointment form contains a questionnaire tab that displays a questionnaire template and allows users to complete it.
- Prerequisite
Resco Suite solution is included in the environment. Woodford project that has Inspections enabled.
- Steps
- Start editing the Appointment form, add a new tab, and change its name to "Questionnaire".
- From the Components pane, drag & drop the HTML web resource to the New Section on the form.
- Search for resco_MobileCRM/WebClient/index.html and click Add.
- In the web resource properties, click Web resource and define the custom parameter:
qplayer={questionnaire_id}.
Click Done. - To display the questionnaire over the whole form, select the Questionnaire tab, and in the properties, check the option Expand the first component to the full tab.
Note | All dependencies, including the questionnaire theming, are taken from the Woodford project with the highest priority. The questionnaire template can be loaded dynamically and passed to the qplayer parameter using JavaScript in the OnLoad event. |
Offline mode
Before enabling offline mode for an app, you must create an offline profile, listing the tables necessary in the offline mode.
- Go to https://admin.powerplatform.microsoft.com/ and select Environments from the menu.
- Click the ellipsis button next to your environment to display all environment actions and select Settings.
- Expand Users + permissions and click Mobile Configuration.
- Click New profile, name it, then click Create.
- Click the newly created profile.
- Click Add table, select "Questionnaire", then click Next. Select All rows (or create a custom filter), then click Save.
- Add the rest of the necessary tables to the offline profile: Question, Question Group, Questionnaire Answer, Mobile Data, Mobile Project, User, Note.
- Publish the offline profile.
With the offline profile ready, follow the procedure for enabling an app for offline use described in the Power Apps documentation. A quick overview of the steps is listed below for your convenience:
- Edit your app in Power Apps.
- Click Settings.
- On the General tab, enable Can be used offline and select the Mobile offline profile.
- On the Features tab, select Enable offline classic.
- Save all changes and publish the app.
You're now ready to test your app on your phone.
- Download the Power Apps app from the store.
- Sign in with your user name.
- Find the published app and start it. The app downloads data for the offline mode.
- Once the download is complete, you are ready to go offline.
Power Pages
Microsoft Power Pages is a platform for creating, hosting, and managing websites. The following example explains how to include the Questionnaire Player on a webpage in a few steps:
- Prepare a special app project in Woodford.
- Create a Power Page and add the Questionnaire Player
- Set up permissions for tables necessary for the Questionnaire Player
- Grant web API access for the same tables
Create a dedicated app project
For version 1.0 of the Power Pages Questionnaire Player, it is essential to have a mobile project in Woodford that is configured to work with Inspections and is named "PPInspectionsPlayer". The simplest way to achieve this is by cloning the predefined Inspections project. Publish the app project afterwards.
Create a Power Page
- Go to https://make.powerpages.microsoft.com/ (Power Pages design studio).
- Ensure you are in the environment with Resco Woodford solution installed.
- Create a new power page or edit an existing one.
- Go to Pages and select the page where you want to add the Questionnaire Player.
- Insert an iframe to the page, then switch to Edit code and use the following code to define the iframe content:
<iframe frameborder="0" id="qplayerIFrame" style="width: 800px; height: 800px; max-width: 100%;"></iframe>
- Include the following script within the page:
<script type="text/javascript" src="/_webresource/resco_MobileCRM/PowerPages/inspectionsPlayer.js"></script>
- Save the modified code, return to Power Page design studio, and click Sync to retrieve the latest code.
Set up table permissions
Add the necessary permissions for the following tables:
- resco_mobileproject – Read access
- resco_mobiledata – Read access
- resco_questionnaire – Read, Write, Update, Delete, Append, Append to
- resco_questionnaireanswer – Read, Write, Update, Delete, Append, Append to
- resco_questiongroup – Read, Write, Update, Delete, Append, Append to
- resco_question – Read, Write, Update, Delete, Append, Append to
- annotation – Read, Write, Update, Delete, Append, Append to
- systemuser – Read, Append, Append to
- webresource – Read, Append, Append to
- Any entity accessible from your questionnaires (e.g., account, contact…)
You can decide what kind of access you want to grant users. Your web can be accessed by anonymous users or authenticated users. The access type might be global or parent, account, or contact. You can learn more about the security model of power pages in official Microsoft documentation. In this document, we describe how to grant access to the mentioned tables for anonymous users.
While editing your site, go to Set up > Table permissions. For each table, repeat the following procedure:
- Click +New.
- Enter the Name of your permission, Website, and the Table Name.
- Set Access Type to "Global".
- Check the required privileges, for example, Read.
- Click Add roles and check role(s) for which the permission is created. In our case, it is Anonymous Users.
- Save all changes.
Set up web API access
Questionnaire Player uses Microsoft Web API service to communicate with the underlying Dataverse organization. You must set the Web API access to the same tables as in the previous step.
- While editing your site, click the ellipsis button in the left pane (just under Set Up) and select Portal Management.
- Select Website > Site Settings from the menu.
- For each table, create two new site settings:
- Enable the web API for this table.
- Set up fields that should be available via web API (or use asterisk for all).
Work with questionnaires
- Initialize the player component
- Call the static "init" method a provide it the iframe from your page.
- Open a questionnaire
- Use the "openQuestionnaire" method to display the questionnaire with a specific ID.
<script type="text/javascript"> $(document).ready(function() { InspectionsPlayer.init(function(player) { player.show(); player.openQuestionnaire("83c7c901-8de2-ed11-a7c7-6045bd8d9620"); }, document.getElementById('qplayerIFrame')); }); </script>
- This opens the player and shows the questionnaire with id "83c7c901-8de2-ed11-a7c7-6045bd8d9620".
List of methods
Here is a list of methods provided by the questionnaire player controller for your reference:
[static] init(ready: (player) -> void, iFrame: HTMLIFrameElement)
Description: This method is essential to initialize the questionnaire player. It establishes the connection between the Power Page controller and the questionnaire player. The callback includes the player object, which provides control over the questionnaire player. This object can be used to manage and interact with the questionnaire player's functionality.
Parameters:
- ready: A callback function that gets executed once the player is ready.
- iFrame: The HTMLIFrameElement associated with the player.
show()
Description: Displays the iframe containing the questionnaire player.
hide()
Description: Hides the iframe containing the questionnaire player.
openQuestionnaire(id: string, regarding?: {id: string, entityName: string})
Description: Loads and displays the questionnaire with the specified ID. The ID should be in GUID format.
You can associate a questionnaire with a specific record by passing a JSON object with two properties to the openQuestionnaire method. This allows you to establish a connection between the questionnaire and a particular record.
Parameters:
- id: The ID of the questionnaire to be displayed.
- regarding [optional]: A JSON object with two properties:
- id: The ID of the regarding object.
- entityName: The entity name of the regarding object
openQuestionnaireWithTemplateName(templateName: string, templateVersion?: number)
- templateName corresponds to the column resco_name
- templateVersion corresponds to the column versionnumber
- If templateVersion is not provided, it searches for the latest modified template with that name.
saveQuestionnaire(close: boolean)
Description: This method saves the currently opened questionnaire. If the close parameter is set to true, the player will also be closed.
Parameters:
- close: A boolean parameter that, when set to true, closes the player after saving the questionnaire.
clearQuestionnaire(force: boolean)
Description: Closes the displayed questionnaire. If the force parameter is set to true, the player will not prompt the user to save data if the questionnaire was modified.
Parameters:
- force: A boolean parameter that, when set to true, closes the questionnaire without prompting for unsaved changes.
executeCommand(commandName: string)
Description: Executes a system or custom command on the questionnaire. You should pass the name of the command to be executed as a parameter.
Parameters:
- commandName: The name of the command to execute.
onCommandsUpdated: (commands: QuestionCommand[]) => void
Description: This callback is triggered when a set of commands associated with the questionnaire is updated. You can use this callback to retrieve the list of commands and their status (enabled/disabled).
Parameters:
- commands: An array of command objects, each containing properties such as name (string), label (string), and isEnabled (boolean).
onShowDetails: (entity: Reference, relationship: object) => void
Description: In cases where a questionnaire contains a lookup question, clicking on the lookup should display details of the related record. However, in Power Pages, the designer has control over what forms or pages to use. Therefore, this callback provides information about the record clicked on, allowing the designer to decide how to display it.
Parameters:
- entity: An object containing fields entityName (string), id (string), and displayName (string), representing the entity related to the clicked record.
- relationship: The relationship object of the questionnaire
onQuestionnaireClosed: () => void
Description: This callback is invoked when the questionnaire is closed
onQuestionnaireSaved: (id: string, status: "active" | "completed" | "cancelled") => void
Description: This callback is invoked when the questionnaire is saved, completed or cancelled
Parameters:
- id: The id of the saved questionnaire
- status: The string representing the status of the saved questionnaire
Appendix A: Sample Power Page code
<p>The Knowledge Base contains numerous support references, created by our support professionals who have resolved issues for our customers. It is constantly updated, expanded, and refined to ensure that you have access to the very latest information.</p>
<div class="row sectionBlockLayout text-left" style="display: flex; flex-wrap: wrap; margin: 0px; min-height: auto; padding: 8px;">
<div class="container" style="padding: 0px; display: flex; flex-wrap: wrap;">
<div class="col-md-12 columnBlockLayout" style="flex-grow: 1; display: flex; flex-direction: column; min-width: 300px;">
</div>
</div>
</div>
<div style="display: flex; flex-direction: row;">
<div style="flex: 2 2 auto">
<h2>Inspections Player</h2>
<iframe id="qplayerIFrame" frameborder="0" style="display: none; width: 800px; height: 800px; max-width: 100%;"></iframe>
</div>
<div style="flex: 1 1 auto; background-color: #ddd; padding: 0px 10px">
<h2>Commands</h2>
<div class="qpCommands"></div>
<h2>Questionnaires</h2>
<span id="myspan1" style="color: blue; text-decoration: underline; cursor: pointer">Request Visit</span><br />
<span id="myspan2" style="color: blue; text-decoration: underline; cursor: pointer">Command Test</span><br />
</div>
<span id="output" style="color: #444"></span>
</div>
<script type="text/javascript" src="/_webresource/resco_MobileCRM/PowerPages/inspectionsPlayer.js"></script>
<script type="text/javascript">
var $qpCommandsDiv = $(".qpCommands");
function commandsUpdated(commands) {
for (var i = 0; i < commands.length; i++) {
var $qpCommand = $("#" + commands[i].name, $qpCommandsDiv);
if ($qpCommand.length === 0) {
$qpCommand = $("<div id=" + commands[i].name + " style='color: blue; text-decoration: underline; cursor: pointer'></div>");
$qpCommandsDiv.append($qpCommand);
$qpCommand.on("click", function(command) {
alert(command.name);
this.executeCommand(command.name);
}.bind(this, commands[i]));
}
$qpCommand.html(commands[i].label);
if (commands[i].isEnabled) {
$qpCommand.css({"cursor": "pointer", "text-decoration": "underline", "color": "blue"});
} else {
$qpCommand.css({"cursor": "inherit", "text-decoration": "none", "color": "silver"});
}
}
}
function showDetails(entity, relationship) {
alert("Show details of: " + JSON.stringify(entity));
}
function questionnaireClosed() {
$qpCommandsDiv.empty();
}
function questionnaireSaved(id, status) {
alert("questionnaire id: '" + id + "', status: '" + status + "'");
}
$(document).ready(function() {
InspectionsPlayer.init(function(player) {
player.onCommandsUpdated = commandsUpdated.bind(player);
player.onShowDetails = showDetails;
player.onQuestionnaireClosed = questionnaireClosed;
player.onQuestionnaireSaved = questionnaireSaved;
player.show();
$("#myspan1").click(function() {
var $qpCommandsDiv = $(".qpCommands");
$qpCommandsDiv.empty();
player.openQuestionnaire("83c7c901-8de2-ed11-a7c7-6045bd8d9620", {id: "36be2493-3bab-eb11-8236-000d3a49e729", entityName: "account"});
});
$("#myspan2").click(function() {
var $qpCommandsDiv = $(".qpCommands");
$qpCommandsDiv.empty();
player.openQuestionnaire("96553634-8de2-ed11-a7c7-6045bd8d9621");
});
}, document.getElementById('qplayerIFrame'));
});
</script>
Replace the IDs in the player.openQuestionnaire method with IDs that exist in your organization.
- Use Case
A questionnaire submitted through a Power Pages portal generates a new opportunity record with a lookup to the questionnaire from which it originated.
This example aims to see this questionnaire displayed directly on the opportunity form.
- Prerequisites
- Parent form with the questionnaire lookup field (Opportunity in this example)
- Web resource „resco_MobileCRM/WebClient/index.html“ named e.g. „WebResource_qplayer“ on this form
- Steps
- Add the questionnaire lookup field and the web resource to the form. More information on how to add resco_MobileCRM/WebClient/index.html web resources here.
- Copy the following js script and modify questionnaireLookupName and orgUrl.
var Example = window.Example || {}; (function () { this.formOnLoad = function (executionContext) { const questionnaireLookupName = "crbb7_questionnaire"; const orgUrl = "https://rescogb.crm4.dynamics.com" const webResourceName = "WebResource_qplayer"; const formContext = executionContext.getFormContext(); const questionnaire = formContext.getAttribute(questionnaireLookupName).getValue(); const questionnaireId = questionnaire[0].id.replace(/{(.*)}/, "$1"); const id = questionnaireId.toLowerCase(); const qplayer= formContext.getControl(webResourceName); if(id) qplayer.setSrc(orgUrl +"/webresources/resco_MobileCRM/WebClient/index.html?data=qplayer%3d"+id); else console.error("Questionnaire Id is not defined"); } }).call(Example);
- Save and upload the js file as a new web resource.
- Select the form, and in the right panel, click Events.
- Create a new Event Handler for On Load.
- Save and publish the form. Run and test in the app.
Limitations
Some advanced questionnaire features are not available on the Power Platform:
- AI Image Recognition
- Barcode scanning
- DocuSign integration
- Optical character recognition
- Reuse answers feature
- Resco JavaScript Bridge
- Mobile reports (cannot be generated directly, but you can set up a Power Automate flow with Resco Reports connector instead)
If you need these use cases, consider switching to Resco mobile apps.