0

I have a ribon rule to either show or hide the Deactivate button for accounts.

It's pretty straightforward

if (typeof (XTC) == "undefined")
{ XTC= { __namespace: true }; }

XTC.RibbonRules = (function () {

    AccountRules = {


        //see if user has roles specified to have the Deactivate button enabled.
        IsDeactivateEnabled: function () {


            var orgName = Xrm.Page.context.getOrgUniqueName();
            var validGuids;
            var allowedRoles = [];

            /*
                put all roles needed to show Account Deactivate button here.

            */
            allowedRoles.push('System Administrator');
            allowedRoles.push('XTC Admin');

            var userRoles = Xrm.Page.context.getUserRoles();

            //user has no assigned roles...
            if (userRoles.length < 1)
                return false;

            var matchingRoles = AccountRules.returnMatchingRoles(userRoles);

            for (var x = 0; x < matchingRoles.length; x++) {
                if ($.inArray(matchingRoles[x].Name, allowedRoles) != -1)
                    return true;
            }

            return false;
        },
        returnMatchingRoles: function (roles) {


            var matches;
            var serverUrl = location.protocol + '//' + location.host + '/' + Xrm.Page.context.getOrgUniqueName();
            var queryUrl = serverUrl + '/XRMServices/2011/OrganizationData.svc/' + 'RoleSet?$filter=';

            for (var x = 0; x < roles.length; x++) {

                if (x == roles.length - 1) {
                    queryUrl += "RoleId eq guid'" + roles[x] + "'";
                }
                else {
                    queryUrl += "RoleId eq guid'" + roles[x] + "' or ";
                }
            }

            $.ajax({
                url: queryUrl,
                type: "GET",
                async: false,
                contentType: "application/json; charset=utf-8",
                datatype: "json",
                beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
                success: function (data, textStatus, XmlHttpRequest) {
                matches = data.d;
                },
                error: function (XmlHttpRequest, textStatus, errorThrown) {
                    alert('OData Select Failed: ' + textStatus + errorThrown + odataSelect); 
                }
            });

            return (matches.results.length > 0) ? matches.results : null;

        }

     };

    return { AccountRules: AccountRules };

})();

So if the user doesn't have a role that's either of the two, the button is deactivated.

My issue is that this isn't running in the context of a form, so including web resources at form config is not working.

For some reason I can't figure out, from there, I have access to jQuery (2.1.1) but none of my other resources.

Is there a way to include web resources system wide so it may be available in this code, just like jQuery seems to be ?

Francis Ducharme
  • 4,848
  • 6
  • 43
  • 81

1 Answers1

3

You can include libraries by making your command look like this:

<CommandDefinition Id="new.incident.Home.ValidateAndResolve.Command">
  <EnableRules>
    <EnableRule Id="Mscrm.SelectionCountAtLeastOne" />
  </EnableRules>
  <DisplayRules />
  <Actions>
    <JavaScriptFunction FunctionName="isNaN" Library="$webresource:xyz_/Scripts/Common/helpers.js" />
    <JavaScriptFunction FunctionName="incidentribbon.validateAndResolve" Library="$webresource:xyz_/Scripts/Ribbon/incident.js" />
  </Actions>
</CommandDefinition>

Note the value of "isNaN" for FunctionName. isNaN is just a globally available JavaScript function that does nothing if you don't pass it any parameters. This is how you get the ribbon to load your library without actually making it call any functions in your library.

Also note that you can either manually edit the command or use a tool like the excellent Ribbon Workbench.

Polshgiant
  • 3,595
  • 1
  • 22
  • 25
  • Thanks, I've seen this before but my ribon XML is huge and I fear editing it manually. I was wondering if there are other ways of doing this. Looks like not. – Francis Ducharme May 19 '16 at 20:22
  • You can use the Ribbon Workbench to add the library, you don't have to manually edit. Note that if the workbench doesn't allow you to choose your library because it wasn't in the solution it downloaded, you can still manually enter it, just make sure to include the $webresource: prefix. – Polshgiant May 19 '16 at 21:45
  • @Polshgiant the 2016 beta version removes the requirement of having to add applicable JS files to the ribbon solution. ;) – Daryl May 20 '16 at 00:12
  • @Daryl Nice! That was such a PITA before I realized you could just type in the web resource manually. – Polshgiant May 20 '16 at 05:45
  • @Polshgiant I've tried that and the namespace of my resource (JS) is only available when the ribon rule is executing in the context of a form (that also loads this resource) but not outside a form context (main Account view for example). Not sure what I'm doing wrong. – Francis Ducharme May 20 '16 at 13:04
  • @Francis Are you saying you want your ribbon scripts and your form scripts to interact with each other? The ribbon loads in a different frame from the form, so if you want your form script to be able to execute a ribbon function, your form script would have to do `window.parent.XTC.RibbonRules.AccountRules.IsDeactivateEnabled`, for example. It's either `window.parent` or `window.top`, don't remember off the top of my head. – Polshgiant May 20 '16 at 15:49
  • @Polshgiant I just want the resources that I make available to my scripts in form events (configured through Form Options) to be available as well in javascript ribon rules (so I don't have to duplicate helper methods and such). – Francis Ducharme May 24 '16 at 20:31
  • If you have a library of helper methods, attach it to your ribbon like my answer shows and also attach it to the form normally. Then, both your ribbon and form code have access to the same helper methods (and I _believe_ that the platform will only download the script once). – Polshgiant May 25 '16 at 13:01