Step 0 – What we want to do:

We have a group of companies in ‘CompanyXYZ’. A total of 4 companies belong to this group (Company A, Company B, Company C and Company D). Now, as a user with a special user (security) role (in this case ‘A’), I want to be able to select one or more records, and thus remove those companies from the composite map:

firma-c3bcbersichtEnlarge Image

We can zoom in on the yellow icon to get this view:

firma-extend-subgrid

Enlarge Image

And with my button “BAAAAM”, I want to get the marked companies out of this group:

BAAAAM

Enlarge Image

The user should confirm, that he is sure about what he does (confirm dialog):

firma-confirmationalert

Step 1: Our Action

Go to your Main Solution and add a new process:Ribbon.JPG

Enlarge Image

It should look like this with two arguments:

action01

Enlarge Image

and you need the workflow itself:Action02

Enlarge Image

The workflow checks the actual user. If the user is not a member of Security Role ‘A’, he isn’t allowed to go on. If he is, then there’s a check, if it’s a group of companies. If no, the workflow is canceled. If yes, it checks if the group of companies contains at least one company. If the workflow could be proceeded, then the field Verbund-ID (which is like a blocknumber for all Companies in a group)  on the form is deleted.

Step 2: Javascript for Action

So now, we need a Javascript which does three things for us:

  1. Show us the Confirm Dialog
  2. Give us an array of GUID-IDs containing the selected companies
  3. Trigger our action

Add a webresource for a Javascript and enter the code there. Should look like this:

if (typeof (JScript_Entities) == "undefined") { JScript_Entities = { __namespace: true }; }
JScript_Entities.accountribbon = {

ButtonClick: function (selectedItem,grid) {

var itemsCount = SelectedItem.length;
var itemsProcessed = 0;

Xrm.Utility.confirmDialog("Do you really want to move company out of this group?",yes,no);

function no(){

return;
}
function yes(){

var organizationUrl = Xrm.Page.context.getClientUrl();

for (var i = 0; i < selectedItem.length; i++) {

selectedItem[i] = selectedItem[i].replace("{", "");
selectedItem[i] = selectedItem[i].replace("}", "");
selectedItem[i] = selectedItem[i].replace("%7b", "");
selectedItem[i] = selectedItem[i].replace("%7d", "");

var data = {
"ReferenceID": selectedItem[i],
};

var query = "accounts(" + selectedItem[i] + ")/Microsoft.Dynamics.CRM.abc_VerbundzuordnungAufheben1";
var req = new XMLHttpRequest();
req.open("POST", organizationUrl + "/api/data/v8.0/" + query, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (this.readyState == 4) {
itemsProcessed += 1;
console.log(itemsProcessed + " of " itemsCount);
if (itemsProcessed == itemsCount) {
grid.refresh();
}
}
};

req.send(window.JSON.stringify(data));

}}

}

}

There’s the confirm dialog which branches in two functions (function yes and function no). If the user cancels, function ‘no’ will be triggered and the code stops (return). If the user wants to go on, the funcion ‘yes’ is executed and per request, the selectedItems are saved into an array (selectedItem), and our Process-action is called (Microsoft.Dynamics.CRM.abc_VerbundzuordnungAufheben1 – see Step 1).

Step 3: Visibility of our Button

In our example, we want to show the Button only if these 3 conditions are true:

  • User must have SecurityRole ‘A’
  • It has to be the form label “Verbund”
  • it has to be a group of companies (not only one single company)

So for that, we need to write a Javascript. Once again, add a new webresource for Javascript:

if (typeof (JScript_Entities) == "undefined") { JScript_Entities = { __namespace: true }; }
JScript_Entities.account = {

    
MyfunctionVisible: function () {


        if (JScript_Entities.account.MyfunctionBtnFunctionExcecuted) {
            return JScript_Entities.account.MyfunctionBtnVisible;
        }
        else {

            var systemuserid = Xrm.Page.context.getUserId().slice(1, -1); 

            var currForm = Xrm.Page.ui.formSelector.getCurrentItem();
            formLabel = currForm.getLabel();

            var req = new XMLHttpRequest();
            req.open("GET", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/systemusers(" + systemuserid + ")/systemuserroles_association?$select=name,roleid", true);
            req.setRequestHeader("OData-MaxVersion", "4.0");
            req.setRequestHeader("OData-Version", "4.0");
            req.setRequestHeader("Accept", "application/json");
            req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
            req.setRequestHeader("Prefer", "odata.include-annotations=\"*\"");
            req.onreadystatechange = function () {
                if (this.readyState === 4) {
                    req.onreadystatechange = null;
                    if (this.status === 200) {
                        var results = JSON.parse(this.response);

                        JScript_Entities.account.MyfunctionBtnVisible = false;

                        for (var i = 0; i < results.value.length; i++) {

                            var securityRoleName = results.value[i]["name"];

                            if (securityRoleName == JScript_Entities.account.SecurityRoleA || securityRoleName == "Systemadministrator") {
                                if (formLabel == "Übersicht Verbund") {
                                    JScript_Entities.account.MyfunctionBtnVisible = true;
                                    JScript_Entities.account. MyfunctionBtnFunctionExcecuted = true;

                                    Xrm.Page.ui.refreshRibbon();
                                }

                            }

                        }

                    } else {
                        Xrm.Utility.alertDialog(this.statusText);
                    }
                }
            };
            req.send();
        }
    },


    errorHandler: function (error) {
        Xrm.Utility.alertDialog(error.message);
    },
    MicroStrategyBaseUrl: null,
    MicroStrategyAvailable: false,
    FormVerbund: "fa5564af-a540-497b-adc3-04dc82bb4077",
    FormA: "2d6aaf5b-5882-4d60-b39a-f128ae179f16",
    FormB: "aca667c1-885e-4047-8893-a3151bc1307b",
    FormC: "24745821-9c21-426c-a4dd-350ccf893a4f",
    AccountCategoryVerbund: 2,
    AccountCategoryKonzernVerbund: 3,
    AccountCategoryKusa: 1,
    SecurityRoleB: "B",
    SecurityRoleA: "A",
    SecurityRoleC: "C",
    MyfunctionBtnVisible: false,
    MyfunctionBtnFunctionExcecuted: false,
    __namespace: true
};

Don’t forget to add the command for refreshRibbon (Page Refresh after workflow Action has finished). I forgot about it and had the following problem then: My button of the Ribbon workbench did exactly what I expected, but the page wasn’t refreshed after my action, so that I didn’t see that it worked and I had to refresh the page manually.

Step 4: Ribbon Workbench

Firma RibbonAnzeige

Enlarge Image

You need to have the Ribbon Workbench and add our button ‘BAAAAM’:

ribbonbutton

Enlarge Image

You need to click on the button to customize it. For the images of this Button, you can simply check this homepage which makes it easy to create a matching icon: FlatIcons

RibbonButtonCommand

Enlarge Image

So now, we need the command, which you have to write into the marked field after having created it in Step 5.

Step 5: Command

The Command is the thing that should be done by clicking the Button. For the Command, you need to use your JavaScript (see Step 2) and put it into the Custom Javascript Action together with the two CRM Parameters

  • SelectedControlSelectedItemIds
  • SelectedControl

RibbonCommand

Enlarge Image

The first Parameter is needed so that the Javascript knows which elements are selected, Javascript gets all GUID-IDs (of the selected companies) in form of an array. The second parameter is needed to execute the Javascript itself I think, to be honest I don’t really know.

There are two Enable-Rules needed:

  • Mscrm.SelectionCountAtLeastOne
  • An own Enable-Rule we have to create first (Myfunction – Step 6)

The Mscrm.SelectionCountAtLeastOne is needed so that the Button only is executable when at least one item is selected. The second (our own rule) is for the visibility depending on different security-roles and different form labels.

Step 6: Enable-Rule

Last, we do need an Enable-Rule so that CRM knows when to show our button or not:

ribbon-enable-rule.png

Enlarge Image

Enter the Javascript-Library and the function and set CRM Parameter to Command Properties.

Don’t forget to publish Ribbon Workbench.

Step 7: Try

Hope this could help you.

Join the conversation! 1 Comment

  1. […] My button ‘VERBANLTEST’ does not yet know what to do. That’s why we enter a command. My command itself is written in a Javascript, the one out of Step 3. So I entered a Custom Javascript Action and inserted my function out of Step 3. In addition to that, I entered an Enable Rule. I used exactly the same Enable Rule as I used when I removed a company out of a group of companies. […]

    Like

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About Miss Ob·so·let

Imperfection is beauty, madness is genious. it is better to be absolutely ridiculous than absolutely boring.

Category

nice to know

Tags

, , , , , , ,