locked
What's wrong with my javascript? RRS feed

  • Question

  • Hello CRMers.  I am trying to get the highest proposal number from my opportunities entity, held in the new_proposal field, and can't understand why the following javascript is not doing it.  I get an object from my loadXML() call, but I can't access the results in maxProposal[0].text.  The error is object required.  I think this means the object returned from my loadXML() calls is empty, but I am not sure how to tell whether that is the case.  If anyone has a link to a good resource on the properties and methods associated with the XMLDOM class, I would appreciate a link.  My Google searches have not been fruitful.

    Thanks in advance for your assistance.

    Dan


     var authenticationHeader = window.opener.GenerateAuthenticationHeader();

     // Define the SOAP XML to access Microsoft Dynamics CRM Web service.
     var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
     "<soap:Envelope xmlns:soap="+
     "\"http://schemas.xmlsoap.org/soap/envelope/\" "+
     "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "+
     "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" +
     authenticationHeader+
     "<soap:Body>" +
     // Specify the RetrieveMultiple message.
     "<RetrieveMultiple xmlns="+
     "\"http://schemas.microsoft.com/crm/2007/WebServices\">" +
     // Specify that this is a QueryByAttribute query.
     "<query xmlns:q1="+
     "\"http://schemas.microsoft.com/crm/2006/Query\" "+
     "xsi:type=\"q1:QueryByAttribute\">"+
     "<q1:EntityName>opportunity</q1:EntityName>" +
     // Set the columns you want to return.
     "<q1:ColumnSet xsi:type=\"q1:ColumnSet\">" +
     "<q1:Attributes>" +
     "<q1:Attribute>new_proposal</q1:Attribute>" +
     "</q1:Attributes>" +
     "</q1:ColumnSet>" +
     // Specify the attribute that you are querying on.
     "<q1:Attributes>" +
     "<q1:Attribute>new_proposal</q1:Attribute>" +
     "</q1:Attributes>";
     "<q1:PageInfo>"+
     "<q1:PageNumber>1</q1:PageNumber>"+
     "<q1:Count>1</q1:Count>"+
     "</q1:PageInfo>"+
     "<q1:Orders>"+
     "<q1:Order>"+
     "<q1:AttributeName>new_proposal</q1:AttributeName>"+
     "<q1:OrderType>Descending</q1:OrderType>"+
     "</q1:Order>"+
     "</q1:Orders>"+
     "</query>"+
     "</RetrieveMultiple>"+
     "</soap:Body>";

      alert(xml);

    // Create an instance of an XMLHTTP object.
     var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    // Configure the XMLHttp object for the
    // Microsoft CRM Web services.
     xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
     xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
     xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
     xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
    // Send the XMLHttp request.
     xmlHttpRequest.send(xml);
    // Capture the XMLHttp response in XML format.
     var resultXml = xmlHttpRequest.responseXML;
    // Create an XML document that you can parse.
     var oXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
     oXmlDoc.async = false;
    // Load the document that has the results.
     oXmlDoc.loadXML(resultXml.xml);
      alert(oXmlDoc);
    var maxProposal = oXmlDoc.getElementsByTagName("new_proposal");
    alert(maxProposal[0].text);

    Thursday, January 7, 2010 7:46 PM

Answers

  • Change the code for order to:

     //Create order expression
    OrderExpression orders = new OrderExpression();
    orders.OrderType =
    OrderType.Descending;
    order.AttributeName = "new_proposal";


    You forgot to specify the column name.
    • Marked as answer by DanP - PAS Monday, January 18, 2010 5:39 PM
    Saturday, January 16, 2010 11:32 AM

All replies

  • Hi Dan,

    At first glance I don't see any issues with your code. If you place a jscript "debugger;" statement on a line in your code and enable debugging in IE then you will be able to step into your code. You can then view the contents of the page variables and interactively travese the XMLDOM object.

    -Tim

    Thursday, January 7, 2010 9:00 PM
  • Hey,

    When you try to write AJAX , Please use the tool availaible in stunnware. It will help you a lot.

    Joe
    Friday, January 8, 2010 1:58 AM
  • try following code and see if this works..


    var authenticationHeader = window.opener.GenerateAuthenticationHeader();
    
     // Define the SOAP XML to access Microsoft Dynamics CRM Web service.
     var xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + 
     "<soap:Envelope xmlns:soap="+
     "\"http://schemas.xmlsoap.org/soap/envelope/\" "+
     "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" "+
     "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">" + 
     authenticationHeader+
     "<soap:Body>" + 
     // Specify the RetrieveMultiple message.
     "<RetrieveMultiple xmlns="+
     "\"http://schemas.microsoft.com/crm/2007/WebServices\">" + 
     // Specify that this is a QueryByAttribute query.
     "<query xmlns:q1="+
     "\"http://schemas.microsoft.com/crm/2006/Query\" "+
     "xsi:type=\"q1:QueryByAttribute\">"+
     "<q1:EntityName>opportunity</q1:EntityName>" + 
     // Set the columns you want to return.
     "<q1:ColumnSet xsi:type=\"q1:ColumnSet\">" + 
     "<q1:Attributes>" + 
     "<q1:Attribute>new_proposal</q1:Attribute>" + 
     "</q1:Attributes>" + 
     "</q1:ColumnSet>" + 
     // Specify the attribute that you are querying on.
     "<q1:Attributes>" + 
     "<q1:Attribute>new_proposal</q1:Attribute>" + 
     "</q1:Attributes>";
     "<q1:PageInfo>"+
     "<q1:PageNumber>1</q1:PageNumber>"+
     "<q1:Count>1</q1:Count>"+
     "</q1:PageInfo>"+
     "<q1:Orders>"+
     "<q1:Order>"+
     "<q1:AttributeName>new_proposal</q1:AttributeName>"+
     "<q1:OrderType>Descending</q1:OrderType>"+
     "</q1:Order>"+
     "</q1:Orders>"+
     "</query>"+
     "</RetrieveMultiple>"+
     "</soap:Body>";
    
      alert(xml);
    
    // Create an instance of an XMLHTTP object.
     var xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    // Configure the XMLHttp object for the 
    // Microsoft CRM Web services.
     xmlHttpRequest.Open("POST", "/mscrmservices/2007/CrmService.asmx", false);
     xmlHttpRequest.setRequestHeader("SOAPAction","http://schemas.microsoft.com/crm/2007/WebServices/RetrieveMultiple");
     xmlHttpRequest.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
     xmlHttpRequest.setRequestHeader("Content-Length", xml.length);
    // Send the XMLHttp request.
     xmlHttpRequest.send(xml);
    // Capture the XMLHttp response in XML format.
     var resultXml = xmlHttpRequest.responseXML;
    
    
    if(resultXml !=null)
    {    
    
    var maxProposals= resultXml.selectNodes("//BusinessEntity/q1:new_proposal"));    
    
         if (maxProposals!=null)
         {
            //alert(InputNode[0].text);
            if(maxProposals[0]!=null)
            {
                var text =maxProposals[0].text;     // same as alert(maxProposal[0].text);
            }
         } 
    }
    
    
    
    

    Hope this helps..
    Sunday, January 10, 2010 12:04 AM
  • I made two modifications to your code as follows:

    "</q1:Attributes>"
    ;  Changed ';' to '+'


    var
    maxProposals= resultXml.selectNodes("//BusinessEntity/q1:new_proposal"));    Removed second ')'

    The results are odd.

    var maxProposals= resultXml.selectNodes("//BusinessEntity/q1:new_proposal"));   

         if (maxProposals!=null)    <---An alert on maxProposals produces an [object] return, as would be expected
         {
            //alert(InputNode[0].text); <--- This uncommented (and changed to maxProposals[0]) is null
            if(maxProposals[0]!=null)
            {
                var text =maxProposals[0].text;     // same as alert(maxProposal[0].text);
            }
         }
    }


    This would seem to infer that no values were found for new_proposal, which is not the case when I run an advanced find.  Any additional advice you could offer is much appreciate.  Also, I will want to return only new_proposal fields that match the pattern 'P%', so if you know how I would do that, that would be great.

    Thanks
    Dan
    Monday, January 11, 2010 9:13 PM
  • Hi Dan,

    can you please remove following lines of code and try again?

    "<q1:PageInfo>"+
     "<q1:PageNumber>1</q1:PageNumber>"+
     "<q1:Count>1</q1:Count>"+
     "</q1:PageInfo>"+


    above line is restircting the result returning from the CRM so please remove it and let me know how you get on?
    Monday, January 11, 2010 9:47 PM
  • Same result.  Its as though there is something wrong with the setup that is causing it to query against the wrong field, but I don't see it.  If it was SQL, we would say

    SELECT MAX(new_proposal)
    FROM opportunity

    where here we have to do more like

    set maxrows = 1

    SELECT new_proposal
    FROM opportunity
    DESCENDING

    the outcome should be the same, though.
    Monday, January 11, 2010 10:14 PM
  • OK, I am changing gears to see if I can get this done.

    I have created a stored procedure that returns the value I am looking for.  I am then trying to instantiate a CallableStatement object, but that generates a syntax error.

    Basically, if I say

    import java.sql.CallableStatement;

    in my form OnLoad script, I get a syntax error, so I have no chance of actually getting to the point where I can use connection.getString to get the result.

    Any ideas?  Any other thoughts on the webservice method of getting this data?  I still cannot understand why the code above didn't work, but I can't waste any more time on it.  Any other way to get this mission accomplished would be welcomed as well.
    Wednesday, January 13, 2010 9:57 PM
  • Hi Dan,

    I think we can make java script code work much easily ..I suggest we debug the existing your code...put debugger statement before the javascript and enable java script debugging  in IE tools --> Internet Options --> Advanced Tab..then check which statement is throwing an error and why and then we can easily resolve that..

    see this article on how to debug the java script ..http://www.programmingfundas.com/blog/2009/03/debugging-javascript-code-in-ms-crm-40/


    regarding your other approach- are you trying to call SQL stored procedure from CRM Form...well i am not sure whether this is possible or not..



    Wednesday, January 13, 2010 10:19 PM
  • Mayank,

    Yes, I was trying to call a stored procedure from the CRM form OnLoad event.  I agree with you; I don't think it works.  I was using some java script examples outside of the CRM world that just don't seem to begin to work within CRM.

    So, back to javascript.  I enabled debugging and that did help.  It showed that the code didn't include a </soap:Envelope>, so I put on at the end after </soap:Body>.

    Now I am receiving this message in resultXml.text after this call:

    var resultXml = xmlHttpRequest.responseXML;

    nodeTypedValue = "soap:ServerServer was unable to process request. 0x8004110f QueryByAttribute must specify a non-empty value array with the same number of elements as in the attributes array. Platform"

    Then maxProposals.item says : Invalid number of parameters.

    My XML string expands to this:

    "<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Header><CrmAuthenticationToken xmlns="http&#58;&#47;&#47;schemas.microsoft.com&#47;crm&#47;2007&#47;WebServices"><AuthenticationType xmlns="http&#58;&#47;&#47;schemas.microsoft.com&#47;crm&#47;2007&#47;CoreTypes">0</AuthenticationType><CrmTicket xmlns="http&#58;&#47;&#47;schemas.microsoft.com&#47;crm&#47;2007&#47;CoreTypes"></CrmTicket><OrganizationName xmlns="http&#58;&#47;&#47;schemas.microsoft.com&#47;crm&#47;2007&#47;CoreTypes">PlantAutomationServices</OrganizationName><CallerId xmlns="http&#58;&#47;&#47;schemas.microsoft.com&#47;crm&#47;2007&#47;CoreTypes">00000000-0000-0000-0000-000000000000</CallerId></CrmAuthenticationToken></soap:Header><soap:Body><RetrieveMultiple xmlns="http://schemas.microsoft.com/crm/2007/WebServices"><query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryByAttribute"><q1:EntityName>opportunity</q1:EntityName><q1:ColumnSet xsi:type="q1:ColumnSet"><q1:Attributes><q1:Attribute>new_proposal</q1:Attribute></q1:Attributes></q1:ColumnSet><q1:Attributes><q1:Attribute>new_proposal</q1:Attribute></q1:Attributes><q1:PageInfo><q1:PageNumber>1</q1:PageNumber><q1:Count>1</q1:Count></q1:PageInfo><q1:Orders><q1:Order><q1:AttributeName>new_proposal</q1:AttributeName><q1:OrderType>Descending</q1:OrderType></q1:Order></q1:Orders></query></RetrieveMultiple></soap:Body></soap:Envelope>"


    Any additional thoughts?  I don't see the problem...

    Thanks
    Dan


    Thursday, January 14, 2010 9:22 PM
  • Hi Dan,

    one thing I suggest is to use stunnerware tool (following) which converts your C# code in to java script and it is really nice tool..

    http://www.stunnware.com/crm2/topic.aspx?id=JSWebService


    now i suggest download this tool and create c# code  for your requirement and this tool will give you correct java script code to use..let me know if you need more information on this..



    Thursday, January 14, 2010 9:53 PM
  • Using the stunnware tool, I wrote this code:

     

    ColumnSet columns = new ColumnSet();
    columns.Attributes =
    new string[] { "new_proposal" };

     

    // Create the ConditionExpression.
    ConditionExpression condition = new ConditionExpression();

     

    // Set the condition for the retrieval to be when the contact's address' city is Sammamish.
    condition.AttributeName = "new_proposal";
    condition.Operator =
    ConditionOperator.Like;
    condition.Values =
    new string[] { "P[0-9][0-9][0-9][0-9][0-9][0-9]" };

     

    // Create the FilterExpression.
    FilterExpression filter = new FilterExpression();

     

    // Set the properties of the filter.
    filter.FilterOperator = LogicalOperator.And;
    filter.Conditions =
    new ConditionExpression[] { condition };

     

    //Create order expression
    OrderExpression orders = new OrderExpression();
    orders.OrderType =
    OrderType.Descending;

     

    // Create the QueryExpression object.
    QueryExpression query = new QueryExpression();

     

    // Set the properties of the QueryExpression object.
    query.ColumnSet = columns;
    query.Criteria = filter;
    query.EntityName =
    EntityName.opportunity.ToString();
    query.Orders =
    new OrderExpression[] {orders};
    query.PageInfo =
    new PagingInfo();
    query.PageInfo.Count = 1;
    query.PageInfo.PageNumber = 1;

     

     

    BusinessEntityCollection result = service.RetrieveMultiple(query);

    This returns the error:
    soap:ServerServer was unable to process request. 0x80040216 An unexpected error occurred. Platform

    I found this article from someone else who had this problem, but the answer was not very enlightening.
    http://social.microsoft.com/Forums/en/crmdeployment/thread/30c8c0c0-040c-4d4f-8c9f-0f0f23c67aaf

    If I comment out the lines concerning the orders, the generated java code works fine.  Unfortunately, I need the MAX value, so I can't leave out the orders decending code!

    I am starting to think the java we had a few posts ago was right, there is just some underlying problem causing the call to fail because of the orders descending code.

    Anyone have any thoughts?

    Thanks
    Dan

    Friday, January 15, 2010 5:22 PM
  • Change the code for order to:

     //Create order expression
    OrderExpression orders = new OrderExpression();
    orders.OrderType =
    OrderType.Descending;
    order.AttributeName = "new_proposal";


    You forgot to specify the column name.
    • Marked as answer by DanP - PAS Monday, January 18, 2010 5:39 PM
    Saturday, January 16, 2010 11:32 AM
  • Nice catch Hanno!  That made the error go away and I can now return the max proposal!

    Muchas gracias!

    Dan
    Monday, January 18, 2010 5:39 PM
  • Hi Dan,

    At first glance I don't see any issues with your code. If you place a jscript "debugger;" statement on a line in your code and enable debugging in IE then you will be able to step into your code. You can then view the contents of the page variables and interactively travese the XMLDOM object.

    -Tim


    Hi, Tim,Can you suggest a jscript "debugger;" as you said? I’d be most grateful for your help.

    "debugger" is just a javascript statement, the javascript equivalent of setting a breakpoint in code. So if you want to start debugging at a certain line in your javascript, you put debugger; in your script on the line above it. So for example: 

    // if script debugging is enabled, it will enter your code here
    debugger;
    
    var foo = crmForm.all.name.DataValue;
    // etc.

    If you have IE8, you can press F12, go to the Script tab and press 'Start debugging'

    Sunday, June 6, 2010 9:18 AM
  • Hi Dan,

    I think we can make java script code work much easily ..I suggest we debug the existing your code...put debugger statement before the javascript and enable java script debugging  in IE tools --> Internet Options --> Advanced Tab..then check which statement is throwing an error and why and then we can easily resolve that..

    see this article on how to debug the java script ..http://www.programmingfundas.com/blog/2009/03/debugging-javascript-code-in-ms-crm-40/


    regarding your other approach- are you trying to call SQL stored procedure from CRM Form...well i am not sure whether this is possible or not..




    I still wonder why though I already got it solved, Any examples for reference?
    Sunday, October 10, 2010 2:39 AM
  • Please note shaun jerrell is a quote spammer that insert hidden links in quotes.

    Please edit your quotes in HTML view to remove the hidden link to the web site shaun jerrell trying  to promote, and beware of users who replies without any information useful in helping the thread starter.



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful, so they will appear differently to other users who are visiting your thread for the same problem.
    Visual C++ MVP
    Monday, December 6, 2010 6:53 PM