Call external Web Service using javascript CRM 2011 RU 12 (Rollup 12) - javascript

Until very recently we'd been using RU 11 within our Dynamics CRM 2011 application but have recently begun a project to eventually move to CRM 2015. We've upgraded to RU 12 and this is where things get fun!
I've managed to sort out a lot of the coding issues that were previously present but cannot for the life of me solve our issue of accessing an external web service, passing parameters along the way and retrieving data back.
At first I had trouble with the "CreateXmlHttp()" function but found a great answer online indicating that the following function would help:
function CreateXmlHttp()
{
var ref = null;
if (window.XMLHttpRequest) {
ref = new XMLHttpRequest();
} else if (window.ActiveXObject) { // Older IE
ref = new ActiveXObject("MSXML2.XMLHTTP.3.0");
}
return ref;
}
This worked fine and as expected, it would have appeared that I could now connect to the service.
However, I am not retrieving any data and this is the issue that is tying me up in knots.
As background, the following is my code to declare a few integer variables before POSTING the xml through to the webservice.
parseInt(lngLicensNr);
parseInt(lngNrOfUsers);
parseInt(lngAnnualWorkingTime);
parseInt(lngIncludedHours);
parseInt(productType);
if (licenceType == 100000000) {
var licenseType = "ltUnlimitedMode";
lngIncludedHours = 1000000;
}
if (licenceType == 100000001) {
var licenseType = "ltHourlyMode";
}
if (lngLicensNr != null && lngNrOfUsers != null && lngAnnualWorkingTime != null && lngIncludedHours != null && productType != null && licenseType != null) {
var errMsg = "";
var errCount = 0;
var xml = "<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">";
xml += "<soap:Body>";
xml += "<GetBaseInstallationKey xmlns=\"http://www.keyservice.com/\">";
xml += "<licensNr>" + lngLicensNr + "</licensNr>";
xml += "<nrOfUsers>" + lngNrOfUsers + "</nrOfUsers>";
xml += "<annualWorkingTime>" + lngAnnualWorkingTime + "</annualWorkingTime>";
xml += "<includedHours>" + lngIncludedHours + "</includedHours>";
xml += "<productType>" + baseProduct + "</productType>";
xml += "<licenseType>" + licenseType + "</licenseType>";
xml += "</GetBaseInstallationKey>";
xml += "</soap:Body>";
xml += "</soap:Envelope>";
try {
Request = CreateXmlHttp();
} catch (ex) {
alert("An error occured while accessing the webservice.\n\n1. " + ex.name + " \n " + ex.message + "\n\n");
errCount = 1;
}
if (errCount == 0) {
try {
Request.open("POST", "http://web01:8080/KeyWebService/KeyWebService.asmx", false);
} catch (ex) {
alert("An error occured while accessing the webservice.\n\n2. " + ex.name + " \n " + ex.message + "\n\n");
errCount = 1;
}
}
if (errCount == 0) {
try {
Request.setRequestHeader("SOAPAction", "http://www.keyservice.com/GetKey");
Request.setRequestHeader("Host", "web01:8080");
Request.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
Request.setRequestHeader("Content-Length", xml.length);
Request.send(xml);
var xmlDoc = Request.responseXML;
} catch (ex) {
alert("An error occured while accessing the webservice.\n\n3. " + ex.name + " \n " + ex.message + "\n\n");
errCount = 1;
}
}
if (errCount == 0 || Request.responseXML != null) {
baseKey = Request.responseXML.text;
} else {
baseKey = "No key generated";
}
}
if (lngLicensNr == null || lngNrOfUsers == null || lngAnnualWorkingTime == null || lngIncludedHours == null || productType == null || licenseType == null) {
alert('Not all parameters have been entered - it is not possible to generate a key without all parameters');
}
Prior to RU 12, the code worked absolutely fine and the last variable "baseKey" was retrieved from the web service.
However, the whole process works perfectly fine now in that it seems to connect ok but just does not retrieve a "baseKey" from the service.
I believe that the issue may be related to deprecated end points or schemas or even just deprecated code that returns and displays the value (i.e. var xmlDoc = Request.responseXML;) but I'm not sure where to resolve.
If anyone has any ideas or can point me in the right direction it would be a big help.

we had similar requirement to call an external Web-service to retrieve the latest contract of a contact and show it on Contact Form.
We had our own definition of latest contract that was implement in a webserivce. So i have to call that webservice on Contact Form Load and pull the data. I could not find an answer. So i am posting my workaround for this.
I had written a plugin that executes on the retrieve of Contact. From the plugin i had call the Webservice and updates the contact fields.
var javaScriptSerializer = new JavaScriptSerializer();
javaScriptSerializer.MaxJsonLength = 104857600; //200 MB unicode
StringBuilder URI = new StringBuilder();
URI.Append(crmRestWebServiceUrl).Append(webServiceMethod);
var request = (HttpWebRequest)WebRequest.Create(URI.ToString());
request.Method = "POST";
request.Accept = "application/json";
request.ContentType = "application/json; charset=utf-8";
//Serialize request object as JSON and write to request body
if (latestMembershipRequest != null)
{
var stringBuilder = new StringBuilder();
javaScriptSerializer.Serialize(latestMembershipRequest, stringBuilder);
var requestBody = stringBuilder.ToString();
request.ContentLength = requestBody.Length;
var streamWriter = new StreamWriter(request.GetRequestStream(), System.Text.Encoding.ASCII);
streamWriter.Write(requestBody);
streamWriter.Close();
}
var response = request.GetResponse();
//Read JSON response stream and deserialize
var streamReader = new System.IO.StreamReader(response.GetResponseStream());
var responseContent = streamReader.ReadToEnd().Trim();
LatestMembershipResponse latestMembershipResponse = javaScriptSerializer.Deserialize<LatestMembershipResponse>(responseContent);
ContactToUpdate["gr_membershiptitle"] = latestMembership.MembershipTitle;
ContactToUpdate["gr_membershipstartdate"] = Convert.ToDateTime(latestMembership.MembershipStartDate);
ContactToUpdate["gr_membershipenddate"] = Convert.ToDateTime(latestMembership.MembershipEndDate);
ContactToUpdate["gr_membershipstatus"] = latestMembership.MembershipStatus;
service.Update(ContactToUpdate);

Related

2 XMLHTTPRequests in one Javascript (Dynamics CRM)

I am currently trying to run 2 separate XMLHTTPRequests in dynamics CRM Javascript to retrieve data from 2 different entities and run code depending on what is retrieved..
I've done my best to try and edit some names for security reasons, but the premise is the same.
My main problem is that the first run of the XMLHTTPRequest (the RA Banner) works fine, but then the second run (the Status Banner) the Readystate that is returned is 2 and stopping.
function FormBanners(formContext) {
//Clear the existing banners
formContext.ui.clearFormNotification("Notif1");
formContext.ui.clearFormNotification("Notif2");
//Get the customer/rep
var customer = formContext.getAttribute("customerid").getValue();
var rep = formContext.getAttribute("representative").getValue();
var contact;
//use the rep if there is one else use the customer
if (rep != null) {
contact = rep;
}
else if (customer!= null) {
contact = customer;
}
//Get the account
var account = formContext.getAttribute("accountfield").getValue();
//As there is a requirement for 2 XMLHTTPRequests we have to queue them
var requestURLs = new Array();
//There will always be a customers or rep on the form
requestURLs.push(Xrm.Page.context.getClientUrl() + "/api/data/v9.1/contacts?$select=new_RA,new_SC,new_VC,new_PR&$filter=contactid eq " + contact[0].id + "", true);
//there may not be an account
if (account) {
requestURLs.push(Xrm.Page.context.getClientUrl() + "/api/data/v9.1/accounts?$select=_new_statusLookup_value&$filter=accountid eq " + account[0].id + "", true);
}
var current = 0;
function getURL(url) {
var req = new XMLHttpRequest();
req.open("GET", requestURLs[current]);
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("Prefer", "odata.include-annotations=\"*\"");
req.onreadystatechange = function () {
if (this.readyState === 4) {
req.onreadystatechange = null;
if (this.status === 200) {
var result = JSON.parse(req.response);
// Creation of the RA Banner
if (current == 0) {
var RA = result.value[0]["new_RA#OData.Community.Display.V1.FormattedValue"];
var SC = result.value[0]["new_SC#OData.Community.Display.V1.FormattedValue"];
var VC = result.value[0]["new_VC#OData.Community.Display.V1.FormattedValue"];
var PR = result.value[0]["new_PR#OData.Community.Display.V1.FormattedValue"];
var Notif = "";
//Only create a notification if any of the above contain "Yes"
if (RA == "Yes" || SC == "Yes" || VC == "Yes" || PR == "Yes") { Notif = "The Customer/Rep has:" }
if (RA == "Yes") { Notif = Notif + " RA,"; }
if (SC == "Yes") { Notif = Notif + " SC,"}
if (VC == "Yes") { Notif = Notif + " VC,"}
if (PR == "Yes") { Notif = Notif + " PR."}
if (Notif != "") {
formContext.ui.setFormNotification(Notif, "INFO", "Notif1");
}
}
//Creation of the Status Banner
else if (current == 1) {
status = results.value[i]["_new_statusLookup_value"];
if (status) {
if (status[0].name != "Open")
var Notif = "The status for the organisation on this case is " + status[0].name + ".";
formContext.ui.setFormNotification(Notif, "INFO", "Notif2");
}
}
++current;
if (current < requestURLs.length) {
getURL(requestURLs[current]);
}
} else {
Xrm.Utility.alertDialog(req.statusText);
}
}
}; req.send();
}
getURL(requestURLs[current]);
}
Can anyone help me out?
So in my example I had made many mistakes. Taking Arun's advice I separated the function out, which made debugging far easier.. it instead was not failing on the XMLHTTP Request because that worked fine, but firefox was crashing when debugging.
So my issues were that I was in the second part:
Used the value of i for results (i was no longer defined)
Getting the "_new_statusLookup_value" would only provide the guid of the lookup I would instead want "_new_statusLookup_value#OData.Community.Display.V1.FormattedValue"
Lets not ignore the fact that because I had copied and pasted many iterations of this code that I was also using "results" instead of "result".
Many little mistakes.. but it happens! Thanks for the help, just goes to show.. typos are our downfall!

Xml.TransformNode(xmldoc) is not supporting in Firefox,chrome,edge

This is the function iam calling to load the data in div
function createApproverList(div, locationId, value)
{
try
{
var url = "dbXML?conn=webddev&sql=Select logon_id, sec_last_name || ', ' || sec_first_name technician_name from w_security where rec_del_flg = 0 AND type_id = 3 order by sec_last_name";
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async = false;
xml.load(url);
div.innerHTML = xml.transformNode(approverXSL.XSLDocument);
document.frmEntry.approverId.value = value;
}
catch (e) {
console.error(e.name + ': ' + e.message)
}
}
But it is working fine internet explorer and not in other browsers so, please help me by converting above one to support in firefox,chrome,edge browsers
Thanks in advance!...

JavaScript: "Syntax error missing } after function body"

Ok, so you know the error, but why on earth am I getting it?
I get no errors at all when this is run locally, but when I uploaded my project I got this annoying syntax error. I've checked the Firebug error console, which doesn't help, because it put all my source on the same line, and I've parsed it through Lint which didn't seem to find the problem either - I just ended up formatting my braces differently in a way that I hate; on the same line as the statement, bleugh.
function ToServer(cmd, data) {
var xmlObj = new XMLHttpRequest();
xmlObj.open('POST', 'handler.php', true);
xmlObj.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlObj.send(cmd + data);
xmlObj.onreadystatechange = function() {
if(xmlObj.readyState === 4 && xmlObj.status === 200) {
if(cmd == 'cmd=push') {
document.getElementById('pushResponse').innerHTML = xmlObj.responseText;
}
if(cmd == 'cmd=pop') {
document.getElementById('messages').innerHTML += xmlObj.responseText;
}
if(cmd == 'cmd=login') {
if(xmlObj.responseText == 'OK') {
self.location = 'index.php';
}
else {
document.getElementById('response').innerHTML = xmlObj.responseText;
}
}
}
}
}
function Login() {
// Grab username and password for login
var uName = document.getElementById('uNameBox').value;
var pWord = document.getElementById('pWordBox').value;
ToServer('cmd=login', '&uName=' + uName + '&pWord=' + pWord);
}
// Start checking of messages every second
window.onload = function() {
if(getUrlVars()['to'] != null) {
setInterval(GetMessages(), 1000);
}
}
function Chat() {
// Get username from recipient box
var user = document.getElementById('recipient').value;
self.location = 'index.php?to=' + user;
}
function SendMessage() {
// Grab message from text box
var from = readCookie('privateChat');
var to = getUrlVars()['to'];
var msg = document.getElementById('msgBox').value;
ToServer('cmd=push','&from=' + from + '&to=' + to + '&msg=' + msg);
// Reset the input box
document.getElementById('msgBox').value = "";
}
function GetMessages() {
// Grab account hash from auth cookie
var aHash = readCookie('privateChat');
var to = getUrlVars()['to'];
ToServer('cmd=pop','&account=' + aHash + '&to=' + to);
var textArea = document.getElementById('messages');
textArea.scrollTop = textArea.scrollHeight;
}
function readCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
The problem is your script on your server is in one line, and you have comments in it. The code after // will be considered as comment. That's the reason.
function ToServer(cmd, data) { var xmlObj = new XMLHttpRequest(); xmlObj.open('POST', 'handler.php', true); xmlObj.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xmlObj.send(cmd + data); xmlObj.onreadystatechange = function() { if(xmlObj.readyState === 4 && xmlObj.status === 200) { if(cmd == 'cmd=push') { document.getElementById('pushResponse').innerHTML = xmlObj.responseText; } if(cmd == 'cmd=pop') { document.getElementById('messages').innerHTML += xmlObj.responseText; } if(cmd == 'cmd=login') { if(xmlObj.responseText == 'OK') { self.location = 'index.php'; } else { document.getElementById('response').innerHTML = xmlObj.responseText; } } } };}function Login() { // Grab username and password for login var uName = document.getElementById('uNameBox').value; var pWord = document.getElementById('pWordBox').value; ToServer('cmd=login', '&uName=' + uName + '&pWord=' + pWord);}// Start checking of messages every secondwindow.onload = function() { if(getUrlVars()['to'] != null) { setInterval(GetMessages(), 1000); }}function Chat() { // Get username from recipient box var user = document.getElementById('recipient').value; self.location = 'index.php?to=' + user;}function SendMessage() { // Grab message from text box var from = readCookie('privateChat'); var to = getUrlVars()['to']; var msg = document.getElementById('msgBox').value; ToServer('cmd=push','&from=' + from + '&to=' + to + '&msg=' + msg); // Reset the input box document.getElementById('msgBox').value = "";}function GetMessages() { // Grab account hash from auth cookie var aHash = readCookie('privateChat'); var to = getUrlVars()['to']; ToServer('cmd=pop','&account=' + aHash + '&to=' + to); var textArea = document.getElementById('messages'); textArea.scrollTop = textArea.scrollHeight;}function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for(var i=0;i < ca.length;i++) { var c = ca[i]; while (c.charAt(0)==' ') c = c.substring(1,c.length); if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length); } return null;}function getUrlVars() { var vars = {}; var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value; }); return vars;}
You're missing a semi-colon:
function ToServer(cmd, data) {
var xmlObj = new XMLHttpRequest();
xmlObj.open('POST', 'handler.php', true);
xmlObj.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlObj.send(cmd + data);
xmlObj.onreadystatechange = function() {
if(xmlObj.readyState === 4 && xmlObj.status === 200) {
if(cmd == 'cmd=push') {
document.getElementById('pushResponse').innerHTML = xmlObj.responseText;
}
if(cmd == 'cmd=pop') {
document.getElementById('messages').innerHTML += xmlObj.responseText;
}
if(cmd == 'cmd=login') {
if(xmlObj.responseText == 'OK') {
self.location = 'index.php';
}
else {
document.getElementById('response').innerHTML = xmlObj.responseText;
}
}
}
}; //<-- Love the semi
}
Additional missing semi-colon:
// Start checking of messages every second
window.onload = function() {
if (getUrlVars()['to'] != null) {
setInterval(GetMessages(), 1000);
}
}; //<-- Love this semi too!
I think you can adapt divide and conquer methodology here. Remove last half of your script and see whether the error is coming. If not, remove the first portion and see. This is a technique which I follow when I get an issue like this. Once you find the half with the error then subdivide that half further till you pin point the location of the error.
This will help us to identify the actual point of error.
I do not see any problem with this script.
This may not be the exact solution you want, but it is a way to locate and fix your problem.
It looks like it's being interpreted as being all on one line. See the same results in Fiddler 2.
This problem could do due to your JavaScript code having comments being minified. If so and you want to keep your comments, then try changing your comments - for example, from this:
// Reset the input box
...to...
/* Reset the input box */
Adding a note: very strangely this error was there very randomly, with everything working fine.
Syntax error missing } after function body | At line 0 of index.html
It appears that I use /**/ and //🜛 with some fancy Unicode character in different parts of my scripts for different comments.
This is useful to me, for clarity and for parsing.
But if this Unicode character and probably some others are used on a JavaScript file in comments before any JavaScript execution, the error was spawning randomly.
This might be linked to the fact that JavaScript files aren't UTF-8 before being called and read by the parent page. It is UTF-8 when the DOM is ready. I can't tell.
It seems there should be added another semicolon in the following code too:
// Start checking of messages every second
window.onload = function() {
if(getUrlVars()['to'] != null) {
setInterval(GetMessages(), 1000);
}
}; <---- Semicolon added
Also here in this code, define the var top of the function
function readCookie(name) {
var i;
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
"Hm I think I found a clue... I'm using Notepad++ and have until recently used my cPanel file manager to upload my files. Everything was fine until I used FireZilla FTP client. I'm assuming the FTP client is changing the format or encoding of my JS and PHP files. – "
I believe this was your problem (you probably solved it already). I just tried a different FTP client after running into this stupid bug, and it worked flawlessly. I'm assuming the code I used (which was written by a different developer) also is not closing the comments correctly as well.

How to Execute FetchXML in CRM 2011 using a CRM 2011 webservice and JavaScript?

I want to execute FetchXML queries in a CRM 2011 environment using the CRM 2011 SOAP web services and JavaScript.
I have found a number of articles like this one showing how to use the 4.0 web service that is still available in the 2011 environment, but I do not want to do this.
This link seems to indicate that IOrganizationService.RetrieveMultiple can handle FetchXML. However, I do not want to use managed code for this.
I've come across this link that shows essentially what I want to do in the RetrieveMultiple function, but I want to be able to pass in existing FetchXML that I've written, not a new filter expression.
To execute fetchxml queries with JavaScript a bunch of frameworks /libraries are available:
XrmSvcToolkit
XrmServiceToolkit
CrmFetchKit.js
Instead of writing the code by hand these libraries provide a simple way to perform several operations and access the results. But take into account that not all libraries (currently) support cross-browser (Q2.2012).
From the link you posted to the Microsoft SDK, you will see how to connect to the ODATA service. As you may have already found, ODATA doesn't allow you to execute fetch.
Instead, you will need to use the SOAP service (/XrmServices/2011/Organization.svc), and pass your fetch using Retrieve Multiple.
Here's a more detailed look at using the 2011 service through JavaScript: http://blog.customereffective.com/blog/2011/05/execute-fetch-from-javascript-in-crm-2011.html
Here is another blog post which parses the returned XML and builds an easily consumable JavaScript object: http://blog.customereffective.com/blog/2011/05/parsing-and-consuming-the-crm-2011-soap-service-inside-javascript.html
The 2011 Organization Service is quite different in it's return, so it won't be plug-n-play from your 4.0 stuff; however, the 2011 endpoint has a lot of nice improvements.
The "Capture Sample HTTP Request and Response" section of this MSDN article outlines how to get a SOAP message that is sent to CRM 2011 from managed code.
The "Execute the Query" section of this MSDN article gives an example of using 2011's IOrganizationService.RetrieveMultiple in managed code to execute a FetchXML query.
Using both of these samples, you can extract a sample SOAP message for RetrieveMultiple that contains a FetchXML query.
The "Create a JScript Library" section of the first MSDN article shows how to perform an Execute request in JavaScript against the 2011 SOAP endpoint. Replace the Assign SOAP request in this example with the RetrieveMultiple SOAP message that you get from executing the managed code.
This enables you to execute a FetchXML request in JavaScript against the 2011 SOAP endpoint.
Here are some snippets from a JavaScript library I wrote using the information above:
(function (window, undefined) {
var _window = undefined;
if (window.Xrm)
_window = window;
else if (window.parent.Xrm)
_window = window.parent;
else throw new Error("Unable to determine proper window");
(function (Crm) {
(function (Service, $, JSON, Xrm) {
if (!Xrm)
throw new Error("Unable to locate Xrm");
if (!JSON)
throw new Error("Unable to locate JSON");
if (!$)
throw new Error("Unable to locate jQuery");
Service.Create = function (ODataSetName, EntityObject) {
if (!EntityObject) {
throw new Error("EntityObject is a required parameter");
return;
}
if (!ODataSetName) {
throw new Error("ODataSetName is a required parameter");
return;
}
var jsonEntityObject = JSON.stringify(EntityObject);
var req = new XMLHttpRequest();
req.open("POST", Service.GetODataEndPoint() + "/" + ODataSetName, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
debuggingCallBack(this);
};
req.send(jsonEntityObject);
};
function debuggingCallBack(req) {
if (req.readyState == 4 /* complete */) {
if (req.status == 201 || req.status == 204 || req.status == 1223) {
//Success
//201 = create
//204 = update
//1223 = delete
}
else {
//Failure
debugger;
}
}
};
Service.Fetch = function (FetchXML) {
var request = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
request += "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\">";
request += "<s:Body>";
request += "<RetrieveMultiple xmlns=\"http://schemas.microsoft.com/xrm/2011/Contracts/Services\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\">";
request += "<query i:type=\"a:FetchExpression\" xmlns:a=\"http://schemas.microsoft.com/xrm/2011/Contracts\">";
request += "<a:Query>";
request += Service.FetchEncode(FetchXML);
request += "</a:Query>";
request += "</query>";
request += "</RetrieveMultiple>";
request += "</s:Body>";
request += "</s:Envelope>";
var req = new XMLHttpRequest();
req.open("POST", Service.GetSOAPEndPoint(), false)
req.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple");
req.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
req.setRequestHeader("Content-Length", request.length);
req.send(request);
results = Service.GetResults(req.responseXML);
return results;
};
Service.Delete = function (ODataSetName, EntityID) {
if (!EntityID) {
throw new Error("EntityID is a required parameter");
return;
}
if (!ODataSetName) {
throw new Error("ODataSetName is a required parameter");
return;
}
var req = new XMLHttpRequest();
req.open("POST", Service.GetODataEndPoint() + "/" + ODataSetName + "(guid'" + EntityID + "')", false)
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
debuggingCallBack(this);
};
req.send();
};
Service.GetServerUrl = function () {
var serverUrl = null;
serverUrl = Xrm.Page.context.getServerUrl();
if (serverUrl.match(/\/$/)) {
serverUrl = serverUrl.substring(0, serverUrl.length - 1);
}
return serverUrl;
};
Service.GetODataEndPoint = function () {
return Service.GetServerUrl() + "/XRMServices/2011/OrganizationData.svc";
};
Service.GetSOAPEndPoint = function () {
return Service.GetServerUrl() + "/XRMServices/2011/Organization.svc/web";
};
Service.GetResults = function (responseXML) {
var sFetchResult = responseXML.selectSingleNode("//RetrieveMultipleResult").xml;
var oResultDoc = new ActiveXObject("Microsoft.XMLDOM");
oResultDoc.async = false;
oResultDoc.loadXML(sFetchResult);
var oResults = new Array(oResultDoc.firstChild.firstChild.childNodes.length);
var iLen = oResultDoc.firstChild.firstChild.childNodes.length;
for (var i = 0; i < iLen; i++) {
var oResultNode = oResultDoc.firstChild.firstChild.childNodes[i];
var oBE = new BusinessEntity(oResultNode.selectSingleNode("//a:LogicalName").text);
var iLenInner = oResultNode.firstChild.childNodes.length;
for (var j = 0; j < iLenInner; j++) {
var oRA = new Object();
var value = null;
if (oResultNode.firstChild.childNodes[j].lastChild.childNodes.length == 3) {
if (oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Id").length == 1)
value = oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Id")[0].text;
if (oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Value").length == 1)
value = oResultNode.firstChild.childNodes[j].lastChild.getElementsByTagName("a:Value")[0].text;
}
if (!value)
value = oResultNode.firstChild.childNodes[j].lastChild.text;
oRA["value"] = value;
oBE.attributes[oResultNode.firstChild.childNodes[j].firstChild.firstChild.text] = oRA;
}
oResults[i] = oBE;
}
return oResults;
};
Service.BusinessEntity = function BusinessEntity(sName) {
this.name = sName;
this.attributes = new Object();
};
Service.FetchEncode = function (FetchXML) {
var c;
var HtmlEncode = '';
if (FetchXML == null) {
return null;
}
if (FetchXML == '') {
return '';
}
for (var cnt = 0; cnt < FetchXML.length; cnt++) {
c = FetchXML.charCodeAt(cnt);
if (((c > 96) && (c < 123)) ||
((c > 64) && (c < 91)) ||
(c == 32) ||
((c > 47) && (c < 58)) ||
(c == 46) ||
(c == 44) ||
(c == 45) ||
(c == 95)) {
HtmlEncode = HtmlEncode + String.fromCharCode(c);
}
else {
HtmlEncode = HtmlEncode + '&#' + c + ';';
}
}
return HtmlEncode;
};
} (Crm.Service = Crm.Service || {}, _window.jQuery, _window.JSON, _window.Xrm));
} (_window.Crm = _window.Crm || {}));
} (window));
"REST is an architectural style in which every resource is addressed by using a unique URI."
http://msdn.microsoft.com/en-us/library/gg334279.aspx
You will not be able to use the REST end-point if you need to use FetchXml.
The alternative is to construct a SOAP message as you saw in your CRM4 examples. I haven't done this myself yet, but perhaps you could use a tool like Fiddler to see what the SOAP message look like so you can replicate them in your environment which your modified FetchXml.
Anyway, just an idea for now. Let me know how it goes, and if you manage to resolve it perhaps post your solution.

Javascript does not recognise dynamic div content

I have a script i have been battling with now for like a week.
I have a page which has a div with id ("content"). Now I loaded some content, a form contained in a div tag to be specific, into this div VIA Ajax, and it is displaying fine
Now, the challenge is - When the form is submitted, Im am calling a function that will disable all the field on the element in that div tag. I always get the error "undefined".
It seems that the div, that i brought in to the page isn't recognized by javascript..
I have searched google, bing, yahoo..i just havent found the solution yet...
Please, what do I do??
I have included the code below --
+++++++++
The code below for my external javascript file
++++++++++++++++++++
// JavaScript Document
var doc = document;
var tDiv;
var xmlHttp;
var pgTitle;
function getXMLObj(){
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
Obj = new XMLHttpRequest();
}
else if (window.ActiveXObject){
// code for IE6, IE5
Obj = new ActiveXObject("Microsoft.XMLHTTP");
}
else{
alert("Your browser does not support Ajax!");
}
return Obj;
}
function loadCont(toLoad, view){
doc.getElementById('loadBlank').innerHTML = '<div id="loading">Processing Request...</div>';
var url;
switch(toLoad){
case 'CI':
pgTitle = "Administration - Company Information";
url = "comp_info.php?v=" + view + "&sid=" + Math.random();
break;
case 'JB':
pgTitle = "Administration - Jobs";
url = "jobs.php?v=" + view + "&sid=" + Math.random();
break;
case 'US':
pgTitle = "Administration - Users";
url = "users.php?v=" + view + "&sid=" + Math.random();
break;
case 'EP':
pgTitle = "Administration - Employees";
url = "emp.php?v=" + view + "&sid=" + Math.random();
break;
case 'AP':
pgTitle = "Administration - Recruitments";
url = "applicants.php?v=" + view + "&sid=" + Math.random();
break;
case 'JV':
pgTitle = "Administration - Recruitments";
url = "jobvacancy.php?v=" + view + "&sid=" + Math.random();
break;
}
xmlHttp = getXMLObj();
if (xmlHttp !== null && xmlHttp !== undefined){
xmlHttp.onreadystatechange = loadingContent;
xmlHttp.open('GET', url, true);
xmlHttp.send(null);
}
}
function loadingContent(){
if (xmlHttp.readyState == 4 || xmlHttp.readyState == 'complete'){
//Show the loading and the title, but hide the content...
if (xmlHttp.status == 200){
doc.getElementById('dMainContent').innerHTML = parseScript(xmlHttp.responseText);
doc.getElementById('loadBlank').innerHTML = '';
}
else{
doc.getElementById('dMainContent').innerHTML = 'Sorry..Page not available at this time. <br />Please try again later';
doc.getElementById('loadBlank').innerHTML = '';
}
}
if (xmlHttp.readyState < 4){
//Show the loading and the title, but hide the content...
doc.getElementById('ActTitle').innerHTML = pgTitle;
doc.getElementById('dMainContent').innerHTML = '';
}
}
function valCompInfo(){
//First Disable All the elements..
alert('I was hree');
DisEnaAll('CompForm');
//Now..lets validate the entries..
}
function DisEnaAll(contId){
//alert(doc.getElementById(contId).elements);
var theId = doc.getElementById(contId).elements;
try{
var numElems = theId.length;
for (var i=0; i < (numElems - 1); i++){
(theId[i].disabled == false) ? (theId[i].disabled = true) : (theId[i].disabled = false);
}
}
catch(e){
var msg = "The following error occurred: \n\n";
msg += e.description
alert(msg);
}
}
// http://www.webdeveloper.com/forum/showthread.php?t=138830
function parseScript(_source) {
var source = _source;
var scripts = new Array();
// Strip out tags
while(source.indexOf("<script") > -1 || source.indexOf("</script") > -1) {
var s = source.indexOf("<script");
var s_e = source.indexOf(">", s);
var e = source.indexOf("</script", s);
var e_e = source.indexOf(">", e);
// Add to scripts array
scripts.push(source.substring(s_e+1, e));
// Strip from source
source = source.substring(0, s) + source.substring(e_e+1);
}
// Loop through every script collected and eval it
for(var i=0; i<scripts.length; i++) {
try {
eval(scripts[i]);
}
catch(ex) {
// do what you want here when a script fails
}
}
// Return the cleaned source
return source;
}
This code is on the main page where the javascript is
<div id="dMainContent">
</div>
</body>
</html>
And finally, the content of the page i am loading via ajax..
<div style="width:738px" id="CompForm">
<div class="tdright">
<?php echo $btnNm; ?>
</div>
</div>
That's the code..
Thanks
The issue is with div tag (id "CompForm") which is not a HTML form.
"elements" is a collection of the form element not div element. So when trying to access div.elements the property is undefined.
See MSDN, form.elements is part of DOM level 1 (according to MSDN)
http://msdn.microsoft.com/en-us/library/ms537449%28v=VS.85%29.aspx
Add your Javascript functions or external JS file to the original page.
this is not JavaScript....
doc.getElementById(contId).elements
but is used in your JavaScript... you will definitely not get anything. (null)
I don't think this is valid either:
theId[i].disabled == false
EDIT: Note per comments: this is NOT the answer :) See comments for details of why.
Left as an answer simply as a learning aid aid as suggested.
Shouldn't
xmlHttp.onreadystatechange = loadingContent;
be
xmlHttp.onreadystatechange = loadingContent();
or
loadingContent();
and that function should return a value if you want to assign it like that...

Categories