Dynamics 365 – Javascript – formContext – Lock form & fields after subgrid is loaded

By Ritchey Hazeu

Hi! In some scenario’s you would like to know if there are any related records and based on this condition, lock a form or any fields (or do any other action!).

First you would like to count the related records which are present in a subgrid:

var gridContext = formContext.getControl("Gridname");// get the grid context

var count = formContext.getControl("Gridname").getGrid().getTotalRecordCount();

And you would like to run this code after the Subgrid is loaded. So you will use the gridContext and let it run on load (apart from the form).

gridContext.addOnLoad(GridOnloadFunction);

How does this code look when you would like to lock fields?

function lockFieldsOnCount(executionContext) {

var formContext = executionContext.getFormContext(); // get the form context
var gridContext = formContext.getControl("Gridname");// get the grid context
    
var GridOnloadFunction = function () { 
var count = formContext.getControl("Gridname").getGrid().getTotalRecordCount();

if (count > 0){
                
var lockAccount = formContext.getControl("field1").setDisabled(true);

var lockContact = formContext.getControl("field2").setDisabled(true);

}

else {
                
var lockAccount = formContext.getControl("field1").setDisabled(false);

var lockContact = formContext.getControl("field2").setDisabled(false);
}
	
};
    gridContext.addOnLoad(GridOnloadFunction); //run onload of subgrid
}

How does this code look when you would like to lock a form?

function lockFieldsOnCount(executionContext) {

var formContext = executionContext.getFormContext(); // get the form context
var gridContext = formContext.getControl("Gridname");// get the grid context
    
var GridOnloadFunction = function () { 
var count = formContext.getControl("Gridname").getGrid().getTotalRecordCount();

if (count > 0){
                
formContext.data.entity.attributes.forEach(function (attribute, index) {    
var control = Xrm.Page.getControl(attribute.getName());
if (control) {
control.setDisabled(true)
	
}
});
	
else {
formContext.data.entity.attributes.forEach(function (attribute, index) {    
var control = Xrm.Page.getControl(attribute.getName());
if (control) {
control.setDisabled(false)
	
}
});
}
	
};
   gridContext.addOnLoad(GridOnloadFunction); //run onload of subgrid
}

Javascript in the Business Process Flow: header_process_ and postfixes

Some things you run into make you go: ‘Oh yeah, totally forgot about that’. I hope most of you don’t have this happen all that often. I ran into one of them a few days ago and thought I’d share.

I was adding a custom filter to a lookup-view in the business process flow, as you can’t change the view in version 8.2 of Dynamics 365 via normal configuration. I ran into a problem where the filter worked on some fields in the flow, but not all. After spending quite some time on this I came to the below conclusions.

When customizing the business process flow via Javascript, you have to take into account that Dynamics adds ‘header_process_’ as a prefix to your fieldname. In addition, there is something else Dynamics does that is less obvious, and maybe less known as it won’t occur all the time. Dynamics adds a postfix of _X to each field that’s repeated in the same business process flow. X here is the next occurrence, starting with 1. The reason this is hard to spot is that it happens all the way at the end of the schema name of a field. Even if you use a tool like the Power Pane (which I would recommend), you probably won’t see the postfix in the schame name unless you hover over it to appear in full.

In my specific case, I work with a branched business process flow in which two similar stages exist, but you only ever see one of them. The invisible stages of the business process flow are also taken into account when the postfixes are appended. I didn’t know about this, and didn’t look closely enough at the exact schema names!

Another reason the search can take so long is that your code doesn’t actually give any errors. It simply doesn’t execute!

Hope this helps some of you out.

Omnichannel Engagement HUB – AADSTS65001: The user or administrator has not consented to use the application with ID

When you would like to work with the whole new Dynamics 365 Omnichannel Engagement HUB and you get the following error:

AADSTS65001: The user or administrator has not consented to use the application with ID

Please follow the next steps to solve it:

Navigate to the applications tab in the Dynamics 365 Administration Center, as stated on the official Microsoft website https://docs.microsoft.com/en-us/dynamics365/omnichannel/try-channels :

Manage Omnichannel application

Click on “Manage” and you will be redirected to the Omnichannel Management screen looking like below:

You can add an organisation and follow trough the steps. Unfortunately most of the times an error will pop-up with the following message:

AADSTS65001: The user or administrator has not consented to use the application with ID ‘someid1’ named ‘Omnichannel for Customer Service’. Send an interactive authorization request for this user and resource. Trace ID: someid2 Correlation ID: someid3 Timestamp: sometimestamp

Transactie-id: someid4

It’s impossible to solve this part in Azure because the consent cannot be managed from there.

That’s why we have to manually consent the Omnichannel Engagement App via an URL:

https://login.microsoftonline.com/common/adminconsent?client_id={client-id}

At the place of the client-id please put the ID ‘someid1’ from your error message. Agree to this consent and now you can install Omnichannel Engagement HUB for your organisation.

Please be aware that you need to be a Global administrator.

Dynamics 365 – How to reset the SharePoint integration button?

When you’ve got a server-based Sharepoint integration with Dynamics 365 you only see the “Enable Server-Based SharePoint Integration” button at the first time you are setting up the integration.

This looks like you can only set-up the integration only once, but in a rare situation you have to set it up again because of:

  1. You’ve got a new SharePoint environment;
  2. Your SharePoint Realm ID has changed.

You can return the integration button by deactivating your active SharePoint Sites by clicking on the below button and select your sites and deactivate them.

This will return your integration button and you can fill in a new SharePoint Realm ID.

Dynamics CRM/365 – Technical things you need to know as a functional consultant

By Ritchey Hazeu (Dynamics 365 Consultant @ Capgemini)

This time: Tools!

When you’re surrounded by developers, you hear a lot of tools which they use to manage their code. They are talking about Visual Studio, Plugin registration tool, SDK, Azure DevOps Server (before TFS), etc. In this blog we will tell you more about those tools and how they are being used.

 

Visual Studio

VS is being used by developers to develop new functionality. VS supports 36 different program languages, has a built-in debugger (a tool to write good code) and a code profiler (measures the functions which are created by the developers).

 

Azure DevOps Server (before TFS)

When you’re working in a team with multiple developers and they are all creating code in Visual Studio you need a place to store this code. You also need to make sure there is a version control. When developer A is working on a piece of code, developer B needs to be aware of this. Azure DevOps Server (before TFS) is providing this so called ‘source code management’. The most powerful thing Azure DevOps Server (before TFS) provides is that it covers the application lifecycle. When you want the store the code in the cloud the name is Azure DevOps (before it was called VSTS), and the code is stored in Azure.

 

SDK (Software Development Kit)

When developers first start working with Dynamics CRM they will download the SDK because it contains the following:

‘The SDK includes an architectural overview of Dynamics 365, the entity model, security model, and web services. Sample code and walkthroughs are provided to guide you through the new features. It also contains information for developers who customize the web client or Dynamics 365 for Microsoft Office Outlook, including scripting, integration of custom webpages, and sample code’ (quoted from https://www.microsoft.com/en-us/download/details.aspx?id=50032)

If will give the developers a bunch of insights in the code which they can use to start off with their own developments.

 

Plugin Registration Tool

Before we will explain this tool, we need to know what plugins are. A plug-in is a custom made (C# or .net) function that is used to extend the standard functionality Dynamics CRM offers. They can run synchronous & asynchronous, when you execute something synchronously, you wait for it to finish before moving on to another task. When you execute something asynchronously, you can move on to another task before it finishes. Plugin act on a certain event in CRM.

An example: You want to automatically send out an e-mail to your customer when the SLA of the case is breached.

The plugin is being created in Visual Studio, with the use of the SDK (you need to include references to Microsoft.Xrm.Sdk) and stored in Azure DevOps Server (before TFS). The plugin is registered in the Plugin registration tool, with the tool you can connect your plugin to different instances in CRM.

 

Custom Workflow

Plugins can be executed on a wide range of events on a CRM entity. Custom workflows are bound to the events which you can see in the CRM application (Create, Update, Status Change, Delete and On assign). Workflows are instead giving (non-technical) users more insight in the process because it’s visible in CRM, unlike the plugin process.

Another difference between workflows and plugin is that workflows are running async and plugins are running sync (read a little bit back for the explanation).

When you create a Custom workflow you also create an assembly and register this just like a Plugin.

 

 

Next article will be about the Architecture of a CRM (on-premise) environment!

Dynamics CRM/365 – Support lifecycle

By Ritchey Hazeu (Dynamics 365 Consultant @ Capgemini)

 

When you’re working for a customer which is using Dynamics CRM it’s always good to know if Microsoft still supports the current version. It depends on the Service Pack which ‘Support end date’ Microsoft applies.

For the older versions Microsoft applies 5 year Mainstream support and 5 year Extended support. Unfortunately this does not count for every Service pack. For Dynamics 365 it’s 5 year Mainstream support and 2 year Extended support.

An example: A customer is using Dynamics CRM 2016 Service Pack 1. This Service Pack has 23-05-2016 as start date and 08-01-2018 as end date. This means that, before the end date, an upgrade needs to be executed to Dynamics CRM 2016 Service Pack for Dynamics 365 (Service Pack 2).

If you want to know which End date is applied to your, or your customer’s Dynamics CRM solution, you can navigate to https://support.microsoft.com/en-us/lifecycle/search and type in the version.

Rewriting Xrm.Page

By Robin Pietens (Dynamics 365 Consultant @ Capgemini)
 
For those that have not yet heard: Microsoft has decided to deprecate the use of Xrm.Page.

Microsoft did indicate their understanding that this feature is used a lot, so they will retain compatibility with it for quite some time. However, new functions should be written in a way that is as future-proof as possible right? For some reason I was unable to easilly find a nice overview of what we should change to deal with this deprecation, and I decided to do something about that.
 

So where we used to write:

function doSomething(){
     var some = Xrm.Page.getAttribute("new_some").getValue(); 
     var action = Xrm.Page.getAttribute("new_action").getValue(); 
     console.log(some + " " + action); 
}

 

We should now do something else, and write:

function doSomething(executionContext){
     var formContext = executionContext.getFormContext(); // get formContext 
     // use formContext instead of Xrm.Page 
     var some = formContext.getAttribute("new_some").getValue(); 
     var action = formContext.getAttribute("new_action").getValue(); 
     console.log(some + " " + action); 
}

 

The other thing to do is to check the box of ‘pass execution context as first parameter’ when setting up the function on the form. If you, like me, make parameters of just about anything, simply pass them with comma’s separated from the executioncontext. Then put everything except the executioncontext in the box as comma separated parameters that will be passed to the function:
 


 

And the function itself will look like this:

function doSomething(executionContext, firstparam, secondparam){
     var formContext = executionContext.getFormContext(); // get formContext
     var some = formContext.getAttribute(firstparam).getValue(); 
     var action = formContext.getAttribute(secondparam).getValue(); 
     console.log(some + " " + action); 
}

 

Any new Scripts that you write should conform to the standard outlined in this blogpost. When making changes to existing libraries, it’s a good idea to take it into account as well. Talk the costs and benefits through with your customer, to keep them as upgrade-proof as possible!

If you want to stay up-to-date with features like this one, keep an eye out for new blogposts and follow us on LinkedIn.

For (hard to find) Microsoft references see: https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/clientapi-form-context

Tips to improve User Adoption

By Robin Schaareman (Dynamics 365 Consultant @ Capgemini)

We have all probably seen a situation like this before, a customer has a Dynamics CRM/365 solution which is in use for several years but the adoption of the system is not satisfying enough. The client asks you to help improve their user adoption of Dynamics CRM/365. Improve user adoption is not an easy task. Via this article I want to give some tips/guidelines that can be used to help a customer improve their user adoption. Let’s start at the beginning….

1.Back to the beginning

To make sure you can start off with a solid solution for your client you need to take them back to the beginning. Why was CRM introduced in the first place? Did CRM solve the problem the client had? These are typical questions you can ask your customer in order to get a good picture of the situation.

 

2.Demonstrate the benefits

There will always be users that did not have a problem with the previous way of working and don’t see the value of the CRM system. Therefor it is extremely important to show the benefits of the CRM system. Even when the system has been live for some time it can be good to demonstrate new features or updates.

 

3.Involve users

Always involve the “daily” users when it comes to maintenance or development of the CRM system. Give them a voice when it comes to new features or changes in the system.  This can be done via several ways. The most important one is communicating about the CRM system. New features, roadmap, tips and tricks etc. Try to find topics which suit the users most so they are actually interested in the message you are spreading. This is one way of communicating, you can also try to organize workshops/training sessions every now and then to demo new features. These sessions are also a great way to interact with the end user!

 

4.Recruit champions!

Reach out to enthusiastic and influential business users to help improve user adoption. This will help with the overall usage of CRM. These so-called champions (this is just an example, you can name this group of people to your liking 😊) are the first point of contact for the other users. They are willing to help other users understand the system and are very valuable for you when it comes to information. Not every user complains via the helpdesk or via a ticketing system about the struggles they have with the system. Champions who are working with these users will pick up some of these complaints, and can inform you, the developper, and even help you think of a solution!

 

5. Keep it simple

CRM is very complex and can be confusing at some points. Keep the interface (e.g. forms ) clean with attributes that users currently need. A cluttered interface won’t help in making the system easy to work with. This can be done via some best practises for example; WYSIATI (What You See Is All There Is) and to let the user flow through the form with the help of a business process flow.

 

6. Sharing is caring

It can be hard in some environments to make this happen but keep in mind that CRM works best if you share the information in it. Dashboards, reports and views will be more valuable if there is a lot of data that can be used. Try to demo this to the business more often to show the benefits, this will help in security discussions you might have with compliance.

 

7. Accessibility

Make the CRM system accessible in various ways so the user can interact with CRM which suits them best. Tablet or Phone, but also on the browser and via the Outlook app! All these ways contribute in user adoption since these options will help the user create records easily.

 

8. Keep up the pace

And at last, keep up the pace! If your time to market is short, users will come to an understanding, that giving feedback about the system actually changes it as well. This will motivate users to actively think about their CRM system.

Dynamics 365 Portals – Set & use cookies

By Ritchey Hazeu (Dynamics 365 Consultant @ Capgemini)

 

Do you want to let users fill in data in the Portal and use this data later in other fields of a WebForm or EntityForm? We can use Cookies to help us achieving this.

In this example we give the customer the opportunity to send in multiple cases. After completing the first case we don’t want them to fill in every field again. We can use Cookies to store information from the first case and use that in the next cases. Let’s start!

 

1. Create a Webform with Contact information page.

 

2. In CRM, navigate to the Contact Information page by going to Portals -> Webforms -> Webform Steps.

 

 

3. Scroll down to the ‘Custom Javascript’ section.

 

Here we fill in the code to store the Cookie for this particular page. In this example we will only store 3 items.

This is the code I’m using:

$(document).ready(function () {
$( "#NextButton" ).click(function() {
console.log("clicked next -> Cookie stored");
document.cookie = "firstname=" + document.getElementById("new_voornaam").value;
document.cookie = "lastName=" + document.getElementById("new_achternaam").value;
document.cookie = "street=" + document.getElementById("new_straat").value;
});
});

 

4. After you submitted the code, you can check if the cookies are being stored.

In Chrome you can use the console by clicking on F12, go to application and then to cookies. It should look like this:

 

 

5. Now the cookies are being stored, we want to use them on other places.

Remember that, in this example, we want to give the customer the possibility to enter multiple cases. On the last page of the Webform we can redirect them to a new case. It’s important to refer to the existing WebPage.

 

 

And besides this you have to fill in the Redirect Webform step at ‘Next step’ at the last page.

 

 

6. We have set the cookies, now we are going to get the cookies.

We can add the new code to the existing code, because we are using it on the same form. If you want to use the data on other forms you have to place the getCookie function on a different page than the setCookie function. The new code will look like this:


function getCookie(name)
{
var re = new RegExp(name + "=([^;]+)");
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}


var firstname = getCookie("firstname");
var lastName = getCookie("lastName");
var street = getCookie("street");

$(document).ready(function () {
$("#new_voornaam").val(firstname);
$("#new_achternaam").val(lastName);
$("#new_straat").val(street);
});

$(document).ready(function () {
$( "#NextButton" ).click(function() {
console.log("clicked next -> Cookie stored");

document.cookie = "firstname=" + document.getElementById("new_voornaam").value;
document.cookie = "lastName=" + document.getElementById("new_achternaam").value;
document.cookie = "street=" + document.getElementById("new_straat").value;
});
});

 

7. If we are creating a new case, the fields are automatically populated:

 

 

If you have extra questions regarding Cookies in Dynamics 365 Portals or other question about Portals & Dynamics 365, please leave a comment.

 

And that’s how the cookie crumbles !