Sergii Gorkun
Sergii Gorkun

Reputation: 216

How could I remake FetchUtil.js for CRM 2011 UR 12

I have to remake FetchUtil.js for using it in CRM 2011 UR 12. I'm not very good in javascript, so I need some help.

This is the native code

 var sFetchResult = xmlhttp.responseXML.selectSingleNode("//a:Entities").xml;
 var resultDoc = new ActiveXObject("Microsoft.XMLDOM");
 resultDoc.async = false;
 resultDoc.loadXML(sFetchResult);

It doesn't work even in IE now, because of .selectSingleNode("//a:Entities").xml I did it like this, but there is no xml field there.

sFetchResult = xmlhttp.responseXML.getElementsByTagName('a:Entities')[0].xml;
    var resultDoc = new ActiveXObject("Microsoft.XMLDOM");
    resultDoc.async = false;
    resultDoc.loadXML(sFetchResult);

Help me to remake this for IE and Chrome. Thanks a lot!

Upvotes: 2

Views: 3714

Answers (3)

Krutika Suchak
Krutika Suchak

Reputation: 21

I was facing the similar issue and I resolved it by using below workaround.

var sFetchResult = xmlhttp.response;
var tempresultDoc = new ActiveXObject("Microsoft.XMLDOM");
tempresultDoc.async = false;
tempresultDoc.loadXML(sFetchResult);

// Now at this point we will have the XML file. Get the singleNode from the XML by using below code.

var resultDoc = new ActiveXObject("Microsoft.XMLDOM");
resultDoc.async = false;
resultDoc.loadXML(tempresultDoc.childNodes[0].selectSingleNode("//a:Entities").xml);

Regards, Krutika Suchak

Upvotes: 2

Daryl
Daryl

Reputation: 18895

If you're looking for a version that doesn't require JQuery, and one that parses the results, check this out. It not only wraps the FetchXML, but also parses the response XML into JavaScript objects for easy retrieval.

Upvotes: 0

Peter
Peter

Reputation: 7804

Here is my calling module (include as webresource)

(function (module, undefined) {

    module.buildFetchRequest = function (fetch) {
        /// <summary>
        /// builds a properly formatted FetchXML request
        /// based on Paul Way's blog post "Execute Fetch from JavaScript in CRM 2011"
        /// http://blog.customereffective.com/blog/2011/05/execute-fetch-from-javascript-in-crm-2011.html
        /// </summary>
        var request = "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
        request += "<s:Body>";

        request += '<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">' +
            '<request i:type="b:RetrieveMultipleRequest" ' +
            ' xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" ' +
            ' xmlns:i="http://www.w3.org/2001/XMLSchema-instance">' +
            '<b:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">' +
            '<b:KeyValuePairOfstringanyType>' +
            '<c:key>Query</c:key>' +
            '<c:value i:type="b:FetchExpression">' +
            '<b:Query>';

        request += CrmEncodeDecode.CrmXmlEncode(fetch);

        request += '</b:Query>' +
            '</c:value>' +
            '</b:KeyValuePairOfstringanyType>' +
            '</b:Parameters>' +
            '<b:RequestId i:nil="true"/>' +
            '<b:RequestName>RetrieveMultiple</b:RequestName>' +
            '</request>' +
            '</Execute>';

        request += '</s:Body></s:Envelope>';
        return request;
    };

    module.sendFetchQuery = function (fetchRequest, doneCallback, failCallback) {
        //path to CRM root
        var server = window.location.protocol + "//" + window.location.host;

        //full path to CRM organization service - you may need to modify this depending on your particular situation
        var path = server + "/XRMServices/2011/Organization.svc/web";

        $.ajax({
            type: "POST",
            dataType: 'xml',
            async: false,
            contentType: "text/xml; charset=utf-8",
            processData: false,
            url: path,
            data: fetchRequest,
            beforeSend: function (xhr) {
                xhr.setRequestHeader(
                    "SOAPAction",
                    "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute"
                ); //without the SOAPAction header, CRM will return a 500 error
            }
        }).done(doneCallback)
          .fail(failCallback);

    };

}(window.xFetch = window.xFetch || {}));

Usage (the parser requires jQuery ... I am doing most of my fetch calls in web resourced html pages so this isn't a problem) this works in IE and Chrome haven't checked firefox but I can't see why it wouldn't work.

   var fetchXml =
                xFetch.buildFetchRequest("<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>" +
                    "   <entity name='ENTITYNAME'>" +
                    "    <attribute name='ATTRIBUTE' />" +
                    "  </entity>" +
                    "</fetch>");

            var entityList = new Array();

            xFetch.sendFetchQuery(fetchXml,
                function (fetchResponse) {

                    // chrome doesn't like the namespaces because of 
                    // selectSingleNode implementations (which make sense btw)
                    // I'll never understand why Microsoft have to pepper their xml 
                    // with namespace dross
                    $(fetchResponse).find("a\\:Entity, Entity").each(function () {

                        var entityData = {};

                        $(this).find("a\\:KeyValuePairOfstringanyType, KeyValuePairOfstringanyType").each(function () {
                            var xmlElement = $(this);
                            var key = xmlElement.find("b\\:key, key").text();
                            var value = xmlElement.find("b\\:value, value").text();
                            entityData[key] = value;
                        });

                        //inner loop
                        $(this).find("a\\:KeyValuePairOfstringstring, KeyValuePairOfstringstring").each(function () {
                            var xmlElement = $(this);
                            var key = xmlElement.find("b\\:key, key").text();
                            var value = xmlElement.find("b\\:value, value").text();
                            entityData[key] = value;
                        });

                        entityList.push(entityData);
                    });

                }, function (jqXhr, textStatus, errorThrown) {
                    // if unsuccessful, generate an error alert message
                });


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

                if (entityList[i].ATTRIBUTE === "Yes" ){ 
                   // DO WHATEVER
                }
            }

I only needed attributes with KeyValuePairOfstringstring and KeyValuePairOfstringanyType but you could parse out any attribute with the right combination of selectors

each item in retrieved

Upvotes: 2

Related Questions