Tuesday, 25 August 2015

Tweak & Modify Ribbon in CRM 2013 Subgrid

Introduction

As we know that ribbon/command in CRM 2013/2015 subgrid can only have ‘+’ button inside and you cannot add ribbon to appear in this subgrid design. Well, this behaviour you cannot change, you cannot add new ribbon, but it does not mean you cannot customize it!

So, I have requirement when the user click +, instead of choosing the existing record using CRM standard lookup (for add existing) or open new window for creating new record, they want to open another custom window, such as CRM Dialog, run custom workflow, run custom script with custom action combination as well, open new web resource, or open new custom website.

So, we can have options such as: Force users to use Associated View (well, this option is not the best option becase why did you even need to put subgrid if you enforce users to use associated view? Hm..in this case you might miss the CRM 2011 version.


So, we need to find the alternative like customizing the ribbon. Well, you cannot modify the behaviour, but I believe you can still achieve it by customizing the ribbon or even its action.

The title must be like Modifying Ribbon in CRM 2013 Subgrid without even modifying the ribbon XML (ribbondiff xml) customization.

Solution

As I read some good articles that it is not recommended to modify the out of the box standard ribbon/command bar, so I take it highly, so I decide to not modify the standard ribbon first, but I still need to fulfill the requirement.

Then, what I do is I try to override the standard function.

Yes, you can attach some script to override the Ribbon Action.

And the good thing here is you can apply the custom action without modifying the Ribbon.XML.
This will be useful to modify the Add New record in Subgrid, Add Existing records in Subgrid, and Add Associated records in Subgrid (N:N) relationship.

*To learn about the behaviour of the subgrid you can refer to these posts:


Then, what solution I did is just to put the additional logic to tweak the existing ribbon javascript calling.

So let’s get started

The Code

Here is the code, it is actually pretty simple if you know the CRM Scripting & basic Javascript overriding concept.

function modifyRibbon() {
    //to store the original function ones
    var originalFunctionAddNewStandard = Mscrm.GridRibbonActions.addNewFromSubGridStandard;
    var originalFunctionAddExistingStandard = Mscrm.GridRibbonActions.addExistingFromSubGridStandard;
    var originalFunctionAssociated = Mscrm.GridRibbonActions.addExistingFromSubGridAssociated;

    //add new standard subgrid
    Mscrm.GridRibbonActions.addNewFromSubGridStandard = function (gridTypeCode, parentEntityTypeCode, parentEntityId, primaryControl, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAddNewStandard(gridTypeCode, parentEntityTypeCode, parentEntityId, primaryControl, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

    //add existing standard subgrid
    Mscrm.GridRibbonActions.addExistingFromSubGridStandard = function (gridTypeCode, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAddExistingStandard(gridTypeCode, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

    //add associate subgrid (N:N)
    Mscrm.GridRibbonActions.addExistingFromSubGridAssociated = function (gridTypeCode, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAssociated(gridTypeCode, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

}

function callPopUp(gridcontrol) {
    if (Xrm.Page.ui.getFormType() == 2) //update {
        //call the pop up
        var dialogoptions = new Xrm.DialogOptions;
        dialogoptions.width = 1080;
        dialogoptions.height = 750;
//You can call pop up or modal dialog or web resource or other script, running dialog, running workflow, or javascript to call custom action
Xrm.Internal.openDialog('http://mycrmserver?id=' + Xrm.Page.data.entity.getId(),
       dialogoptions, null, null, function (retval) { gridcontrol.Refresh() });
        gridcontrol.Refresh();
    }
}

Remember that this is the key:

//to store the original function ones
    var originalFunctionAddNewStandard = Mscrm.GridRibbonActions.addNewFromSubGridStandard;
    var originalFunctionAddExistingStandard = Mscrm.GridRibbonActions.addExistingFromSubGridStandard;
    var originalFunctionAssociated = Mscrm.GridRibbonActions.addExistingFromSubGridAssociated;

And this also mandatory to override:

//add new standard subgrid
    Mscrm.GridRibbonActions.addNewFromSubGridStandard = function (gridTypeCode, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAddNewStandard(gridTypeCode, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

    //add existing standard subgrid
    Mscrm.GridRibbonActions.addExistingFromSubGridStandard = function (gridTypeCode, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAddExistingStandard(gridTypeCode, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

    //add associate subgrid (N:N)
    Mscrm.GridRibbonActions.addExistingFromSubGridAssociated = function (gridTypeCode, gridControl) {
        if (gridControl.get_id() != "subgrid_id") {
            originalFunctionAssociated(gridTypeCode, gridControl);
        }
        else {
            callPopUp(gridControl);
        }
    }

You can choose want to put in the N:N or 1:N subgrid only.

Which this one is optional and replaceable, replace it by your OWN CODE LOGIC

And this is the condition to whether you want to override the ribbon with your own custom action or not
if (gridControl.get_id() != "subgrid_id") 

Because once you implement this method, by default all subgrid will be overriden unless you want to exclude it, I just want to  make sure only applicable for the “subgrid_id” so I put that condition, for other subgrid it will still using the original one.

*You just need to put it in the form scripting and call on form onload

image

Result


*Alert action (if put alert action in the action logic)

image

*Calling the pop up

image

image

Then when I click the X button will refresh the ribbon because of this code:
function (retval) { gridcontrol.Refresh() }

Please refer to this for specific article:

http://inogic.com/blog/2014/09/alternative-to-showmodaldialog/

In this case, take not of this: Use of Xrm.Internal is unsupported as per SDK
But, anyway, in my post, this is just an example, you can change the logic to anything you want.
Can call custom dialog or workflow.

Mscrm.FormAction.launchOnDemandWorkflowForm
http://ribbonworkbench.uservoice.com/knowledgebase/articles/132235-create-a-workflow-short-cut-ribbon-button-no-code

Can refer to this good article:
http://ribbonworkbench.uservoice.com/knowledgebase/articles/140652-create-a-run-dialog-short-cut-ribbon-button

Or can use to open the modal popup (like my example) or open the entity form:
http://msdn.microsoft.com/en-us/library/gg328483.aspx

Or you can use to show alert and confirm dialog:
http://blogs.msdn.com/b/shraddha_dhingra/archive/2013/12/22/alertdialog-and-confirmdialog-in-crm-2013.aspx

Or even you can block user to add new record or link records:







All can be done using form scripting without even touching the ribbon.xml

*Note: This action is not documented in the SDK, use this to help you fulfil the requirement, The advantage on this action is in the next release, it might break, but you just need to modify the form scripting.

Like I did in CRM 2013 and CRM 2015, the scripting is changed from

Mscrm.GridRibbonActions.addExistingFromSubGridStandard to Mscrm.GridCommandActions.addExistingFromSubGridStandard

*For CRM 2015 you can refer to this article:
CRM 2015 Update 1 Code

This will be useful for you in case you do not want to use the standard subgrid function and there is no way like CRM 2011 you can have ribbon/command bar appearing same exactly like you have in Associated View.

Hope this helps!

Thanks.

1 comment:

  1. Hi!
    Your article looks very helpful. Except solution doesn’t work.

    I just want to replace + AddExisting button beheviour with default AddNew.
    But getting error on the screen:

    Error
    An error has occurred.

    Try this action again. If the problem continues, check the Microsoft Dynamics CRM Community for solutions or contact your organization's Microsoft Dynamics CRM Administrator. Finally, you can contact Microsoft Support.
    Can you advise?



    function modifyRibbonon() {
    //to store the original function ones
    var originalFunctionAddNewStandard = Mscrm.GridRibbonActions.addNewFromSubGridStandard;

    //add existing standard subgrid
    Mscrm.GridRibbonActions.addExistingFromSubGridStandard = function (gridTypeCode, gridControl) {
    alert(gridControl.get_id());
    if (gridControl.get_id() == "subgrid_id") {
    originalFunctionAddNewStandard(gridTypeCode, gridControl);
    }
    }
    }

    Thank you!

    ReplyDelete

My Name is..