Dynamics 365 Editable Grid Events & Methods


The much-awaited capability of editing a CRM grid inline is one of the new features in Dynamics 365. Using this functionality improves the productivity of the CRM user by significantly reducing the number of mouse clicks.


Editable grid is available as a UI control which can be added to an entity through entity customization. Addition of the editable grid to the desired entity will make all the entity views for that entity inline editable allowing the users to make in-place updates to the values of the grid view columns. The editable grid control also enables a very useful feature to group the records in the view by selected view columns. Using form customizations, this control can also be added to the subgrids on the form enabling them for inline edits.

To interact with the editable grid developers can write scripts which can be executed on the following grid events.

  • OnChange
  • OnRecordSelect
  • OnSave

The following table details out several editable grid methods to access the grid control elements and their values programmatically.


Description Implementation

Grid Methods

getGrid() –  Returns the grid object

–  Contains information about all the grid elements

CRM Editable Grid 1
getRows() –  Returns an enumerable collection of data row of the grid

–  Contains information about the row elements of the grid

–  Returns all the rows displayed on the UI

CRM Editable Grid 2
getSelectedRows() –  Returns an enumerable collection of selected data rows of the grid

–  Returns data related to one or more rows selected on the UI

CRM Editable Grid 3
getTotalRecordCount() –  Returns the count of the number of rows in an entity view  

CRM Editable Grid 4

Grid Row Methods


getKey(), getData().getEntity(), getData().getEntity().getEntityName(), getData().getEntity().attributes

–  Returns an object of the row data specific to the record displayed/selected in the grid

–  Contains entity information, attributes information and related entity information

–  Attributes returned are limited to the columns presented in the editable grid

CRM Editable Grid 5


Grid Cell Methods





–  Each grid cell is associated with a UI control like text, lookup, picklist

–  Information related to these control is available in the attribute collection

–  These controls can be accessed in a similar way as on the entity form


CRM Editable Grid 6


Hope you find it useful, stay tuned for more updates.

Thank you,
Swaroop Deshmukh
Lead Dynamics CRM Consultant @ Adisys


Dynamics CRM Scripting for Business Process Flows

Dynamics CRM 365/ Dynamics CRM 2015/ CRM 2016 lets the developers interact with the business process flows by writing client-side scripts. Business Process flow actions can be performed programmatically by making use of the methods under Xrm.Page.data.process and Xrm.Page.ui.process namespaces.

To interact with the business process flow, in addition to the entity form events, two new events onStageChange() and onStageSelected() event are provided by the client API.

Below is the list of methods for tapping into the  Business Process Flow capability.

Method Description Implementation
Process Methods
getEnabledProcesses –  Executes asynchronously

–  Retrieves the information about all the business process flows enabled for the entity

–  Returns a dictionary object where Id is the key and Name is the value


Xrm.Page.data.process.getEnabledProcesses(function (processes) {

for (var processId in processes) {

alert(“Id:” + processId + “, Name:” + process[processId]);



setActiveProcess –  Executes asynchronously

–  Sets the business process flow for the entity passed as a parameter

–  Returns the status of the operation (success or invalid)

// Set Active Process

Xrm.Page.data.process.setActiveProcess(processId, function (status) {



getActiveProcess –  Retrieves the information about the active business process flow for the entity

–   Returns an object containing the data for the active process

var id, processName, stageCount;

var activeProcess = Xrm.Page.data.process.getActiveProcess();

if (activeProcess != null) {

// Get Process Id

id = activeProcess.getId();

// Get Process Name

processName = activeProcess.getName();

// Get Process stage count

stageCount = activeProcess.getStages().getLength();


setDisplayState –  Displays the business process flow as expanded or collapsed

–  Display state is passed as a string parameter to the function

if (Xrm.Page.ui.process.getDisplayState() == “collapsed”) {

// Set the display as expanded



else {

// Set the display as collapsed



setVisible –  Shows or hides the business process flow

–  Boolean parameter to show (true) or hide (false) the process

if (!Xrm.Page.ui.process.getVisible()) {

// Show the business process flow



else {

// Hide the business process flow



Stage Methods
getStages –  Retrieves the information about a specific stage in the process identified by the index value

–  Returns an object containing the data related to a particular stage in a process

var stageObj,stageId, stageName, stageEntityName, stageCategory, stageStatus;

var activeProcess = Xrm.Page.data.process.getActiveProcess();

if (activeProcess != null) {

// Get the First stage object of the process

stageObj = activeProcess.getStages().get(0);

// Get Stage Id

stageId = stageObj.getId();

// Get Stage Name

stageName = stageObj.getName();

// Get Stage Entity name

stageEntityName = stageObj.getEntityName();

// Get Stage Category

stageCategory = stageObj.getCategory().getValue(); // – integer value of the stage

// Get Stage Status

stageStatus = stageObj.getStatus(); // – active/inactive


getActiveStage –  Returns an object representing the current active stage of the process var activeStage;

// Get Active Stage object

activeStage = Xrm.Page.data.process.getActiveStage();

setActiveStage –  Executes asynchronously

–  Sets a completed stage for the current entity as the active stage

// Sets the Stage identified by the id as the active stage

Xrm.Page.data.process.setActiveStage(stageId, function (data) {



getActivePath –  Retrieves a collection of stages currently in the active path.

–  Contains information for completed stages, current active stage as well as predicted future stages based on the data on the current record and branching rules for the process


// Get Active Path

var activePath = Xrm.Page.data.process.getActivePath();

if (activePath != null) {

activePath.forEach(function (stage, n) {

alert(” Stage Index: ” + n + “\n Entity: ” + stage.getEntityName() + “\n StageId: ” + stage.getId() + “\n Status: ” + stage.getStages());





Step Methods
getSteps –  Retrieves the information of all the steps in a particular stage of the process var stepCollection, stepCount, stepObj,stepName,stepAttributeName,isStepReq,stepType;

var activeStage = Xrm.Page.data.process.getActiveStage();

if (activeStage) {


// Get Step count

stepCount = activeStage.getSteps().getLength();

// Get the Steps of a stage

stepCollection = activeStage.getSteps();

// Get the First Step object of the stage

stepObj = activeStage.getSteps().get(0);

// Get the Step Name

stepName = stepObj.getName();

// Get the Step Attribute name

stepAttributeName = stepObj.getAttribute();

// Check whether the Step is required

isStepReq = stepObj.isRequired();

// Get the Step type

stepType = stepObj.getStepType();


Navigation Methods
moveNext –  Progresses the process to the next stage

–  Works only when the selected stage and the active stage are the same

–  Triggers the onStageChange event

–  Returns the status in a callback function indicating the operation status (success, crossEntity, end, invalid)

// Move Next

Xrm.Page.data.process.moveNext(function (status) {

if(status == “success”)

alert(“Moved to next stage”);


movePrevious –  Moves the process to the previous stage

–  Works only when the selected stage and the active stage are the same

–  Triggers the onStageChange event

–  Returns the status of the operation

// Move Previous

Xrm.Page.data.process.movePrevious(function (status) {

if(status == “success”)

alert(“Moved to previous stage”);



Event Handler Methods
addOnStageChange –  Adds a function as an event handler for the onStageChange event

–  Event handler function executes when Next or Previous button is clicked on the process UI

// Add onStageChange event handler



function stageChanged(execContext)


// Get direction

var direction = execContext.getEventArgs().getDirection();

// Get the current stage object

var currentStage = execContext.getEventArgs().getStage();


removeOnStageChange –  Removes a function as an event handler for the onStageChange event // Remove onStageChange event handler


addOnStageSelected –  Adds a function as an event handler for the onStageSelected event

–  Event handler function executes whenever a stage of an business process flow is selected

// Add onStageSelected event handler



function stageSelected(execContext)


// Gets the current stage

var currentStage = execContext.getEventArgs().getStage();


removeOnStageSelected –  Removes a function as an event handler for the onStageSelected event // Remove onStageSelected event handler


Hope you will find it useful!

Adisys Engineering Team

Dynamics CRM 2016 Solution Patching

Dynamics CRM 2016 Enhancement- Solution Patching

As we already know concept of solution was introduced in Dynamics CRM 2011, in Dynamics CRM 2015 there was cosmetic changes made in solution management. In this release they added significant improvements to manage solutions in better and deeper way.

Earlier versions if you wanted to export any field or any new specific customization of an entity you had to export entire entity itself.

If we export the solution, the entity and all customizations and related components like views, relationships, Ribbon, UI changes and any other components that are part of the entity are exported in that solution. Importing entity means deploying all customization to target environment. Sometime we want to avoid this but it was not possible in earlier versions.

In Dynamics CRM 2015 there was no enhancement in Solution framework but in Dynamics CRM 2016 Solutions and customizations are more manageable.

In Dynamics CRM 2016 we can include specific components in solution instead of including all entity assets as shown in picture below:

Dynamics CRM 2016 Solution Patch - Account

Dynamics CRM 2016 Solution Patch – Account


I will give a real time example that we face challenges every time. Suppose we deployed some solution to production.  Sometimes, due to last minute change requests or emergency fixes need to push to UAT or Production environment right after deployment. We are already working on some enhancement in DEV and in between we did Emergency fix to CRM Form or fields and created new fields. In this scenario we just want to deploy emergency fixes that we did for form or created new field or modified anything in field or any change to a particular form for particular entity that is already deployed to production.  We don’t want to deploy other enhancements that are still under development. We just want to deploy the  Hotfix (patch).

In this scenario Dynamics CRM 2016 solution patching made it easier!

To address this, you can create and publish solution patches on top of existing solution that contains subcomponents of entities.

I will explain how solution patching works here:

I have created a MyTestPathEntity Entity and added to solution MyEntity.

Now I will create a patch for solution. You can select a solution and click Clone a Patch button. See in below screen shot You can change the display name and build numbers of the solution. You can’t change the Major and Minor versions.

Dynamics CRM 2016 Solution Clone to Patch

Dynamics CRM 2016 Solution Clone to Patch

It will create a solution Patch like below. It will be a blank solution without any component.

Dynamics CRM 2016 Solution

Dynamics CRM 2016 Solution

 When you will try to edit the Parent solution it will show below message.

Dynamics CRM 2016 Solution - Custom Entity

Dynamics CRM 2016 Solution – Custom Entity

In Patch solution I have just added my custom field.
Field name is new_testoptionset.
Field is of type OptionSet.
I have added one more OptionSet value to existing OptionSet.
Now as Parent solution is already available in target environment you can just import Patch solution.

Solution should be deployed to target environment in below order.

  • Parent solution
  • Patch Solution

You can’t deploy Patch solution before Parent solution. You might be thinking how CRM is checking the dependency.

Patches are stored in the CRM database as Solution table. ParentSolutionId attribute indicates that the solution is a patch.  Patch solution will be having reference to Parent solution.

If you have more than 1 patch. You should deploy in the order you have created.

If you want to merge parent solution and all patches you can clone solution.  It will create an incremented version of solution and merge patches into the new solution. When you will click Clone solution button you can see below screen. You can modify Major minor version but you can’t modify Build and revision number.

Now after clone I can see only 1 solution with incremented version.

Dynamics CRM 2016 Solution - Version

Dynamics CRM 2016 Solution – Version

Few important things to remember as per the MSDN.

  • Patches can only be created from a parent solution.
  • The patch parent can’t be a patch. It won’t allow you to create a Patch from Patch.
  • Patches can only have one parent solution.
  • A patch creates a dependency (at the solution level) on its parent solution.
  • You can only install a patch if the parent solution is present.
  • A patch version must have the same major and minor number, but a higher build and release number, than the parent solution version number. The display name can be different.
  • If a solution has patches, subsequent patches must have a numerically higher version number than any existing patch for that solution.
  • Patches support the same operations as solutions, such as additive update, but not removal. You cannot remove components from a solution using a patch.
  • Patches exported as managed must be imported on top of a managed parent solution. The rule is that patch protection (managed or unmanaged) must match its parent.
  • Don’t use unmanaged patches for production purposes.
  • Patches are only supported in CRM organizations of version 8.0 or later.

We would love to hear your feedback.
Happy CRMing!!
Adisys Engineering Team


CRM 2013 – JavaScript – Unsaved Message due to a jQuery masking Plug-In

CRM Unsaved Message due to a JQuery masking plugin

We have a requirement to have telephone number displayed with the carrier code. It can be implemented by using a JQuery masking plugin. The details can be found in this blog: http://slalomdotcom.wordpress.com/2011/06/03/crm-field-masking-with-jquery/

However the record status will be changed to ‘unsaved changes’ after page loading. CRM pops up message ‘Your changes have not been saved. To stay on the page so that you can save your changes, click Cancel’ when user leave page without any changes. This is very frustrating and it can’t be resolved directly by setting Xrm.Page.data.setFormDirty(false)


Finally we decided to use JS to Mask the telephone fields instead of JQuery plugin. Following is the sample code:

On Form Load:

Function formatTel()


var sTmp = Xrm.Page.getAttribute(“telephone1”).getValue();

sTmp = sTmp.replace(/[^0-9]/g, “”);

switch (sTmp.length) {

case 10:

sTmp = “(” + sTmp.substr(0, 3) + “) ” + sTmp.substr(3, 3) + “-” + sTmp.substr(6, 4);



sTmp = “(” + sTmp.substr(0, 3) + “) ” + sTmp.substr(3, 3) + “-” + sTmp.substr(6, 4) + ” x” + sTmp.substr(10, sTmp.length – 10)






//On Field change reset submit mode to always:

function changeSubmitMode(mode) {

// mode = “always”

if (Xrm.Page.getAttribute(“telephone1”).getSubmitMode() != mode ){






// Remove phone masking before saving back to CRM

function removePhoneMasking(text) {

text = text.replace(“(“, “”);

text = text.replace(“)”, “”);

text = text.replace(“-“, “”);

text = text.replace(/ /g, “”);

return text;



I hope you find it useful!

Author: Zhe Chen
Title: Lead Dynamics CRM Consultant @ Adisys
Email: zhechen@adisys.co

Do you have a Dynamics CRM Data Archival Strategy for your implementation!

Lets deploy the Dynamics CRM as your CRM solution. Often times Data Archival is an after thought. This should be part of the early design scope. We should estimate the growth of the records in the CRM System. There are tools available in the market, however the Dynamics Sure Step process provides basic calculator. Adisys team has built similar tool this can help to determine the Data growth by month, quarter and year. This also helps to determine fastest growing entities in the CRM system.

Our consultants mastered in providing the CRM Data Archival Strategy to our customers and also we have numerous tools which can enable easily to define the strategy. This can help your system to optimize time to time and keep system updated.

We will keep update more data facts in this section, please stay tuned. Meantime, if you have any queries don’t reach out our staff at sales@adisyscorp.com.