Monday, March 18, 2013

Apply Languages Settings for Custom UI in MS CRM 2011:

Our previous blog, we posted how to apply language settings for Custom Entity.  This post will cover one of the approach in displaying Messages and Fields for a Custom UI (HTML web resource, aspx).  This approach looks appropriate as we leverage the CRM translate mechanism for our custom UI and store the relevant translations within CRM.

To achieve this follow the steps:
1.       Create custom entity with all necessary Labels and Messages to be displayed in custom page.
2.       Export and Import Translation.
3.       Retrieve the custom entity metadata to display in custom page.
i.e.  If a Message “Are you sure want to delete?” is used in a custom page which need to translate as per user’s language setting.
 

Then this message needs to be field Label in MS CRM custom entity.
 
 

Similarly, all necessary Labels need to be created in MS CRM.  Then this entity need to be exported for translation and translated following the steps mentioned in my previous blog (refer date here). Once this is done, retrieve this custom entities metadata to display the Labels and Messages the custom pages.
Below is code to retrieve the custom entity labels from metadata using JavaScript:
function RetrieveMetadataRequest() {

            var requestMain = ""
            requestMain += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
            requestMain += "  <s:Body>";
            requestMain += "    <Execute xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
            requestMain += "      <request i:type=\"a:RetrieveEntityRequest\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
            requestMain += "        <a:Parameters xmlns:b=\"http://schemas.datacontract.org/2004/07/System.Collections.Generic\">";
            requestMain += "          <a:KeyValuePairOfstringanyType>";
            requestMain += "            <b:key>EntityFilters</b:key>";
            requestMain += "            <b:value i:type=\"c:EntityFilters\" xmlns:c=\"http://schemas.microsoft.com/xrm/2011/Metadata\">Entity Attributes Privileges Relationships</b:value>";
            requestMain += "          </a:KeyValuePairOfstringanyType>";
            requestMain += "          <a:KeyValuePairOfstringanyType>";
            requestMain += "            <b:key>MetadataId</b:key>";
            requestMain += "            <b:value i:type=\"c:guid\" xmlns:c=\"http://schemas.microsoft.com/2003/10/Serialization/\">00000000-0000-0000-0000-000000000000</b:value>";
            requestMain += "          </a:KeyValuePairOfstringanyType>";
            requestMain += "          <a:KeyValuePairOfstringanyType>";
            requestMain += "            <b:key>RetrieveAsIfPublished</b:key>";

            requestMain += "            <b:value i:type=\"c:boolean\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">false</b:value>";
            requestMain += "          </a:KeyValuePairOfstringanyType>";
            requestMain += "          <a:KeyValuePairOfstringanyType>";
            requestMain += "            <b:key>LogicalName</b:key>";
            requestMain += "            <b:value i:type=\"c:string\" xmlns:c=\"http://www.w3.org/2001/XMLSchema\">new_languagesettings</b:value>";
            requestMain += "          </a:KeyValuePairOfstringanyType>";
            requestMain += "        </a:Parameters>";
            requestMain += "        <a:RequestId i:nil=\"true\" />";
            requestMain += "        <a:RequestName>RetrieveEntity</a:RequestName>";
            requestMain += "      </request>";
            requestMain += "    </Execute>";
            requestMain += "  </s:Body>";
            requestMain += "</s:Envelope>";
            var req = new XMLHttpRequest();
            req.open("POST", _getServerUrl(), false)
            // Responses will return XML. It isn't possible to return JSON.
            req.setRequestHeader("Accept", "application/xml, text/xml, */*");
            req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            req.setRequestHeader("SOAPAction", http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute);
            var successCallback = null;
            var errorCallback = null;

            req.onreadystatechange = function () { RetrieveMetadataResponse(req, successCallback, errorCallback); };
            req.send(requestMain);
        }

        function RetrieveMetadataResponse(req, successCallback, errorCallback) {
            if (req.readyState == 4) {
                if (req.status == 200) {
                    LabelXml = req.responseXML;
                }
                else {
                    errorCallback(_getError(req.responseXML));
                }
            }
        }

        function _getError(faultXml) {
            ///<summary>
            /// Parses the WCF fault returned in the event of an error.
            ///</summary>
            ///<param name="faultXml" Type="XML">
            /// The responseXML property of the XMLHttpRequest response.
            ///</param>
            var errorMessage = "Unknown Error (Unable to parse the fault)";
            if (typeof faultXml == "object") {
                try {
                    var bodyNode = faultXml.firstChild.firstChild;
                    //Retrieve the fault node
                    for (var i = 0; i < bodyNode.childNodes.length; i++) {
                        var node = bodyNode.childNodes[i];
                        //NOTE: This comparison does not handle the case where the XML namespace changes
                        if ("s:Fault" == node.nodeName) {
                            for (var j = 0; j < node.childNodes.length; j++) {
                                var faultStringNode = node.childNodes[j];
                                if ("faultstring" == faultStringNode.nodeName) {
                                    errorMessage = faultStringNode.text;
                                    break;
                                }
                            }
                            break;
                        }
                    }
                }
                catch (e) { };
            }
            return new Error(errorMessage);
        } 

Finally the LabelXml custom web page will display messages and Labels as per user’s language code.
 

This will be the message displayed if the user’s language setting had French selected. 
Hope this was helpful.

No comments:

Post a Comment