Wednesday 21 June 2017

{know-how} Or condition between linked entities or multiple entites in MSCRM Fetchxml

I have seen many struggling to achieve an OR condition between filters in parent entity and the linked entity. So today lets see how to overcome this issue and how to achieve an OR condition spanning between multiple entities.

Scenario:
I want to select an account with specific phone number or its primary contacts phone number is equal to the given number

Gap:
In this scenario we may not able to form an or condition for the filters as the filters are split between the parent(account) and the linked entity(contact) in advanced find editor. But the same can be achieved in fetchxml.

Solution:
Fetchxml supports conditions from other linked entities, the trick is to use an attribute called entityname in condition node to specify which entity it links to. The same is highlighted below.



<fetch version="1.0" output-format="xml-platform" mapping="logical" >
    <entity name="account" >
        <attribute name="accountid" />
        <filter type="or" >
            <condition attribute="telephone1" operator="eq" value="1234" />
            <condition entityname="contact" attribute="telephone1" operator="eq" value="1234" />
        </filter>
        <link-entity name="contact" alias="contact" from="contactid" to="primarycontactid" />
    </entity>
</fetch>

Hope this helps!

{know-how} Set a lookup value on create/update of a record using MSCRM WebApi - An undeclared property Error



Recently faced an error while creating and updating records in CRM using WebAPI. The issue was around setting a lookup value and following is the error message

An undeclared property new_primaryincident which only has property annotations in the payload but no property value was found in the payload. In OData, only declared navigation properties and declared named streams can be represented as properties without values.


Fix:
The issue is due to the fact that whenever we set a lookup value we need use schema name and not the logical name. In my case I had to use "new_PrimaryIncident" instead of  "new_primaryincident".

Code snippet:

// code with issue
"new_primaryincident@odata.bind":"/incidents(10000000-0000-0000-0000-000000000000)" 

// code after fix
"new_PrimaryIncident@odata.bind":"/incidents(10000000-0000-0000-0000-000000000000)"

Hope this helps!

Tuesday 20 June 2017

{know-how}MSCRM open external url using Xrm.Utility.openWebResource - D365



Hello All,

Good to be back with another know-how post, lets see how to open an external url using Xrm.Utility.OpenWebresource

Scenario:
On click of search ribbon button in account form of CRM, open an external url(bing search) using Xrm.Utility.openWebResource

Why to use Xrm.Utility.openWebResource
Window.open is not a supported method to open a webresource

How?
  1. Open a custom HTML webresource using openWebResource method and pass the encoded external URL as query string parameter
  2. In the webresource, redirect to the encoded URL in  parameter.

Steps and code explanation: 
  1. Create a custom HTML webresource(use the code below).
  2. Onload of page, call a js function named getParameters.
  3. The function will retrieve the encoded URL available in query string
  4. Then it will redirect to the encoded external URL(Bing search)

Code snippets

To open Webresource:
var customParameters = encodeURIComponent("<URL goes here>");
Xrm.Utility.openWebResource("ram_webContainer.html", customParameters)

HTML webresource named ram_webContainer.html:

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />
    <script type="text/javascript" src="ClientGlobalContext.js.aspx"></script>
    <script type="text/javascript">
        var CRMCustomParameters = [];
        var getParameters = function () {
            var Parameters = GetGlobalContext().getQueryStringParameters();
            if (Parameters && Parameters.Data) {
                location.href = Parameters.Data;
            }

        }
       
    </script>
</head>
<body onload="getParameters()">

</body>
</html>

Hope this helps!

Friday 16 June 2017

{know-how} Editablegrid disable fields conditionally using Javascript - Dynamics CRM D365 - D365_EditableGrid#1


Editable grid is an awesome way to manage related child records effectively and efficiently within few clicks and I personally love it for the same. For this kind of requirements, building a custom grid was the story for long time and now Editable grid is a real savior.

Before deep diving into code , below are the supported JavaScript events for editable grid. 

Scenario: In account form we have contact editable grid. Whenever the account name is DisableFields(felt lazy to find another field :P), disable all the fields in the editable grid row.

Event Registration:
  1. Open form editor and then open editable grid properties
  2. Navigate to Events tab and select Event named OnRecordSelect
  3. Add a function to the event.While adding function do not forget to enable "Pass execution context as first parameter"


Code Explanation:
To access the current row(entity record) we need the editable grid's formcontext which is a part of the context passed as first parameter. From there the rest of the code is similar to our traditional js implementations. 

function setFieldsDisabled(context) {
    var name = Xrm.Page.getAttribute("name").getValue();
    if (name == "DisableFields") {
        var contact = context.getFormContext().data.entity;
        contact.attributes.forEach(function(field, i) {
            field.controls.get(0).setDisabled(true);
        });
    }
}

Hope this helps! 

Friday 9 June 2017

Mobile compatible development - disable all fields using JS - Microsoft Dynamics CRM - MoCA_Tip#3


Hello All,

Lets go though a quick tip on best practice around disabling all fields using JavaScript in MoCA.

Issue:
In traditional CRM JS development, we tend to use  getDisabled function to identify whether a control is disabled or not and setDisabled to enable or disable a field.

But in MoCA there are some controls which do not expose the above functions which result in JS error(not defined or not found).

Fix:
Before calling the function validate whether the function exist or not  and then call the same. By this way we can avoid unnecessary chaos in our JS.

Code Snippet:

if (control && control.getDisabled && !control.getDisabled()) {
   control.setDisabled(true);
}


Refer this blog for MoCA compatible disable all fields script

Don't forget to go through previous tips if you have missed,
  1. Form Selector and its usage