Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Friday, 2 June 2017

How to assign a record to the current user via JavaScript

Recently I got a requirement from the customer to create a ribbon button on a custom entity so that a user can click on that button and get the record assigned to him/herself. You might wonder why create a ribbon button when we have the “Assign” button clearly. Reason is we need to do some web service calls to external systems too when user click on that button; so we needed a custom ribbon button.


I could achieve this easily by creating a JavaScript function like below to update the owner id and call this function on click of the ribbon button.


function AssignRecordToCurrentUser() {   
    var currentRecordId = Xrm.Page.data.entity.getId().replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');       

    var entity = {};
    entity["ownerid@odata.bind"] = "/systemusers(" + currentUserId + ")";   
    var req = new XMLHttpRequest();
    req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")", false); // my entity name is new_workitem
    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.onreadystatechange = function () {
        if (this.readyState === 4) {
            debugger;
            req.onreadystatechange = null;
            if (this.status === 204) {
                //Success - No Return Data - Do Something
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(entity));
} 

This works fine as long as the current user has got the write privileges to the entity. If the current user has read only rights this throws an exception. So when I was searching the web I found that we need to pass an additional parameter and impersonate the call. So I used the GUID of a system administrator like below.

function AssignRecordToCurrentUser() {
    var currentRecordId = Xrm.Page.data.entity.getId().replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');

    var entity = {};
    entity["ownerid@odata.bind"] = "/systemusers(" + currentUserId + ")";
    var impersonateUserId = "A734DA29-7993-DE11-BECE-005056B47DB0";// GUID of the system administrator
    var req = new XMLHttpRequest();
    req.open("PATCH", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")", false);// my entity name is new_workitem
    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("MSCRMCallerID", impersonateUserId);
    req.onreadystatechange = function () {
        if (this.readyState === 4) {
            debugger;
            req.onreadystatechange = null;
            if (this.status === 204) {
                //Success - No Return Data - Do Something
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(entity));
}

But this did not work either. L

So I came up with another idea!!
I created an action to assign the record and then called that action from the JavaScript function. Here in this action I am passing the current user as an input parameter to the action.

My action looks like below:
















This is the parameter:














And the JavaScript to call the action is like this:

function AssignRecordToCurrentUser () {
    debugger;
    var currentRecordIdString = Xrm.Page.data.entity.getId();
    var currentRecordId = currentRecordIdString.replace("{", '').replace("}", '');
    var currentUserId = Xrm.Page.context.getUserId().replace("{", '').replace("}", '');
    var entityName = "new_workitem";

    ////using action
    debugger;
    var parameters = {};
    var currentuser = {};                                      
    currentuser.systemuserid = currentUserId;
    currentuser["@odata.type"] = "Microsoft.Dynamics.CRM.systemuser";
    parameters.CurrentUser = currentuser;

    var req = new XMLHttpRequest();
    req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.2/new_workitems(" + currentRecordId + ")/Microsoft.Dynamics.CRM.new_Assignworkitemtocurrentuser", false);
    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.onreadystatechange = function () {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 204) {
                debugger;
                //Success - No Return Data - Do Something
            } else {
                debugger;
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(parameters));
}

Make sure you activate your action.
I hope this will help you!

Tuesday, 18 April 2017

How to read configuration data from an xml web resource via JavaScript?

There are situations where you need to keep some environment specific configuration data (e.g. URLs) in a single location without repeating them in all scripts so that all your form scripts can access them.

This way you need to change those variables in only one location when you go from one environment to the other (i.e. Dev to Test and UAT etc.)

Let’s say you have created an XML web resource named new_ApiConfiguration.xml.
And assume your web resource looks like this:

<SacConsultingApi>
<CreateApiUrl>https://webapi.sacconsulting.com.au/crmdev/api/record?id=</CreateApiUrl>
<UpdateApiUrl>https://webapi.sacconsulting.com.au/crmdev/api/update?recId=</UpdateApiUrl>
<ExpireApiUrl>https://webapi.sacconsulting.com.au/crmdev/api/expire?recId=</ExpireApiUrl>
</SacConsultingApi>

And you can access these configurations inside you custom form scripts by calling the following function.

Declare the variables on top and call the function.

var CreateApiUrl;
var UpdateApiUrl;
var ExpireApiUrl;

function GetWebApiConfigurations() {   
    var serverUrl = Xrm.Page.context.getClientUrl();
    var xmlConfigPath = serverUrl + "/WebResources/new_ApiConfiguration.xml";
    var xmlHttp = new XMLHttpRequest();
    xmlHttp.open("GET", xmlConfigPath, false);
    xmlHttp.send();
    var doc = xmlHttp.responseXML;
    CreateApiUrl = doc.getElementsByTagName("CreateApiUrl")[0].textContent;
    UpdateApiUrl = doc.getElementsByTagName("UpdateApiUrl")[0].textContent;
    ExpireApiUrl = doc.getElementsByTagName("ExpireApiUrl")[0].textContent;
}

Remember to change the name of the web resource to your web resource name.


This way when you deploy solutions from one environment to the other you don’t need to go and change your configurations in hundred places.

See this post to know how to achieve this via C# code (Plug-ins of custom workflow activity)

Monday, 20 March 2017

How to call a plugin from a JavaScript or a ribbon button?


Sometimes there are situations where you need to call a plugin from a JavaScript or click of a ribbon button. With the help of actions and latest web API this is easily achievable.

Step 1

Under Processes create a new Process with Category selected as Action; give a name and select the entity. In this example I have selected Account as the entity. It’s just a blank action with no arguments or steps.



Step 2

Create your plugin and register your plugin on that action you created. Make sure you have activated your action and published. Otherwise you will not see the newly created action in the plugin registration tool. If you still don’t see your action name in messages in plugin registration tool close the plugin registration tool and open again. It should resolve this.



Step 3

In your JavaScript on account form use following code; replace the action name with the unique name of your action.
In this example replace new_AccountAction with your unique name.
function CallAction() {   
    var currentRecordIdString = Xrm.Page.data.entity.getId();
    var currentRecordId = currentRecordIdString.replace("{", '').replace("}", '');
    var query = "accounts(" + currentRecordId + ")/Microsoft.Dynamics.CRM.new_AccountAction";
    var req = new XMLHttpRequest();
    var url = Xrm.Page.context.getClientUrl() + "/api/data/v8.0/" + query;
    req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v8.0/" + query, false);
    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.onreadystatechange = function () {
        if (this.readyState == 4) {
            req.onreadystatechange = null;
            if (this.status == 204) {
                //Xrm.Utility.alertDialog("Action Called");
            }
            else {
                var error = JSON.parse(this.response).error;
                Xrm.Utility.alertDialog(error.message);
            }
        }
    };
    req.send();
}


That’s all. Then you can call this function from your ribbon button if you need to.



How to tackle Concurrent Business Process flows

Dynamics 365 has introduced the new feature of Concurrent Business Process Flows. Here is a couple of good articles on that: http://dev...