AJAX - Return Arrays and Structs to your JavaScript with XML: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
(New page: = Functionality = The VDF AJAX Library provides the functionality for developers to call published methods within a WBO and receive a return value (for Functions). This is done using a Re...)
 
Line 44: Line 44:
   Function_Return aXML
   Function_Return aXML
  End_Function  // NameChanges
  End_Function  // NameChanges
I just wanted to ask 'why' this works ....
    Get paXml of hoXml to aXml
    Send Destroy of hoRoot
    Send Destroy of hoXML
    Function_Return aXML
End_Function
Is it because VDF does not ACTUALLY destroy and objects untill it gets to end_function ? because returning a handle to something you have just destroyed doesn't look quite right ? ie you are returning a handle to nothing or something that might still exist at that point ?
VDF has a special XmlHandle return type for returning a hoXML object and the tidying up after itself
Is there a reason why this has not been used in this case ? eg would this work for AJAX ?
{ Published = True  }
{ Description = ""  }
Function NameCasing String sName Returns XMLHandle
  Handle hoRoot hoXML hoEvent
  Address aXml
  // create xml document
  Get Create U_cXMLDOMDocument                            to hoXML
  Set pbValidateOnParse of hoXML                          to False
  Get CreateDocumentElement of hoXML "response"          to hoRoot
  Send AddElement of hoRoot "lowercase" (lowercase(sName))
  Send AddElement of hoRoot "uppercase" (Uppercase(sName))
  Send AddElement of hoRoot "propercase" (Uppercase(Left(sName,1))+lowercase(Right(sName,(length(sName)-1))))
  Function_Return hoXML  // runtime will transfer and then destroy this object because of XMLHandle return type
End_Function  // NameChanges


= Parsing the XML in JavaScript =
= Parsing the XML in JavaScript =

Revision as of 11:32, 17 December 2008

Functionality

The VDF AJAX Library provides the functionality for developers to call published methods within a WBO and receive a return value (for Functions). This is done using a Remote Method Invokation (RMI). Using RMI's for returning a single datatype is fairly straight-forward. If you want to return a Struct, Array , or an Array of Structs you need to do some more work. Remember, you are returning these datatypes to JavaScript and there is no direct translation from a Windows Struct or Array to a JavaScript Struct or Array.

The Solution

The solution is to return the data in an XML document. XML can be formatted to return a Struct of data, and Array, or an Array of Structs.


Calling the WBO Function from JavaScript

This is an example of a JavaScript function using the RMI to call a function of the webapp. It called the Function NameCasing of the oMyWBO. It passes a single argument of sName. When the Function returns, it will call the JavaScript method onNameCasing.

function nameCasing(sName) {
  var oRMI = new VdfRemoteMethodInvocation(true, "oMyWBO", "get_NameCasing", null, onNameCasing);
  oRMI.addParameter(sName);
  oRMI.sendCall();
}


Creating the XML in the WBO

1) create an XML document
2) add elements to the XML
3) get the memory address of the XML document
4) destroy the VDF connection to the address
5) return the memory address. This will return the XML document to the JavaScript

{ Published = True  }
{ Description = ""  }
Function NameCasing String sName Returns Address
  Handle hoRoot hoXML hoEvent
  Address aXml
  // create xml document
  Get Create U_cXMLDOMDocument                            to hoXML
  Set pbValidateOnParse of hoXML                          to False
  Get CreateDocumentElement of hoXML "response"           to hoRoot
  Send AddElement of hoRoot "lowercase" (lowercase(sName))
  Send AddElement of hoRoot "uppercase" (Uppercase(sName))
  Send AddElement of hoRoot "propercase" (Uppercase(Left(sName,1))+lowercase(Right(sName,(length(sName)-1))))
  Get paXml of hoXml to aXml
  Send Destroy of hoRoot
  Send Destroy of hoXML
  Function_Return aXML
End_Function   // NameChanges


I just wanted to ask 'why' this works ....

   Get paXml of hoXml to aXml
   Send Destroy of hoRoot
   Send Destroy of hoXML
   Function_Return aXML

End_Function

Is it because VDF does not ACTUALLY destroy and objects untill it gets to end_function ? because returning a handle to something you have just destroyed doesn't look quite right ? ie you are returning a handle to nothing or something that might still exist at that point ?

VDF has a special XmlHandle return type for returning a hoXML object and the tidying up after itself

Is there a reason why this has not been used in this case ? eg would this work for AJAX ?


{ Published = True } { Description = "" } Function NameCasing String sName Returns XMLHandle

 Handle hoRoot hoXML hoEvent
 Address aXml
 // create xml document
 Get Create U_cXMLDOMDocument                            to hoXML
 Set pbValidateOnParse of hoXML                          to False
 Get CreateDocumentElement of hoXML "response"           to hoRoot
 Send AddElement of hoRoot "lowercase" (lowercase(sName))
 Send AddElement of hoRoot "uppercase" (Uppercase(sName))
 Send AddElement of hoRoot "propercase" (Uppercase(Left(sName,1))+lowercase(Right(sName,(length(sName)-1))))
 Function_Return hoXML  // runtime will transfer and then destroy this object because of XMLHandle return type

End_Function // NameChanges

Parsing the XML in JavaScript

1) check to see if there were any errors
2) make sure we have a return value
3) create the XML parser object
4) get the values from the XML

function onNameCasing(oRMI) {
  // If no errors
  if (oRMI.iErrorNumber==0){
    if (oRMI.sReturnValue!=null){
      // create XML parser
      try { // code for IE
        xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async="false";
        xmlDoc.loadXML(oRMI.sReturnValue);
      } catch(e) { // code for Mozilla, Firefox, Opera, etc.
        try {
          parser=new DOMParser();
          xmlDoc=parser.parseFromString(oRMI.sReturnValue,"text/xml");
        } catch(e) {
          alert(e.message);
          return;
        }
      }
    }
    if (xmlDoc!=null){
      var sLower="", sUpper="", sProper="";
      sLower=xmlDoc.getElementsByTagName("lowercase")[0].childNodes[0].nodeValue;
      sUpper=xmlDoc.getElementsByTagName("uppercase")[0].childNodes[0].nodeValue;
      sProper=xmlDoc.getElementsByTagName("propercase")[0].childNodes[0].nodeValue;
      //todo: do something with these values
    }
  }
}