Communication

Web Properties

Control Template

 

The communication is mainly handled by the framework. This means that the framework determines which information is sent back and forth and actually makes the AJAX request. Instead of directly calling a web-service the controls tell the framework that they want call a function on the server and the framework assembles and sends the call, handles the response and notifies the control.

Server Actions

A server action is a call to a specific function of a web object on the server. The framework makes sure that the call is assembled and contains the current application state (synchronized web properties and rowids). The main function for doing this is available on the df.WebObject class and is inherited by all framework controls.

serverAction (df.WebObject)

This method is used to send a call to the DataFlex object represented by the JavaScript object. The framework will assemble the request and send it to the server.


Parameter

Type

Description

sMethod

String

Name of the published DataFlex function / procedure (no msg_ or get_ should be passed).

aParams

Array

Array with the parameters that need to be passed to the function / procedure.

aOptData

Struct

(optional) Struct of type tWebValueTree objects that can be sent as additional complex data. Pass null if no data needs to be sent.

fOptHandler

Function

(optional) Handler function executed when the call is finished and a response is received.

oOptEnv

Object

(optional) Object that will be the context when the handler function is called. The JavaScript this will point to this object. If no object is passed the JavaScript web object itself will become the context.

 

Calling the Server

The example below shows how to publish a function on the server. Inside a class this is usually done inside the End_Construct_Object.

Function SayHello String sTo String sFrom Returns Boolean

    Send ShowInfoBox (SFormat("%1 says hi to %2", sFrom, sTo))

    

    Function_Return True

End_Function

Procedure End_Construct_Object

    // Publish methods....

    WebPublishFunction SayHello

    

    Forward Send End_Construct_Object

End_Procedure

Calling this function from JavaScript is done using the serverAction. The function name is passed as string and the parameters as an array. A handler function can be passed that is called when the action is completed. The handler function will be called with an event object (df.events.JSEvent) as parameter that has a property sReturnValue that contains the return value. Note that the return value is always passed as a string regardless the DataFlex type returned.

this.serverAction("SayHello", [ "the World", "John" ], null, function(oEvent){

    //  Executed after call has returned

    if(oEvent.sReturnValue === "1"){

        

    }

}, this);

 

Passing Complex Data

Some controls will need to be able to pass complex sets of data to the server. Examples within the framework are the grid and treeview controls. The framework has a standard format for sending data to the server which is the tWebValueTree. Data formatted in this struct format can be passed to the server with server actions. The format is based on the existing value tree format which has the advantage that any struct can be represented in this format.

Struct tWebValueTree

    String v

    tWebValueTree[]c

End_Struct

In JavaScript the df.sys.vt.serialize function is able to convert any data object into a value tree. The developer himself is responsible for delivering the data in the right format. The example below shows how to add a complex set of data to a server action.

//  Create data objects    

var oData =  {

   labels : ["January","February","March","April","May","June","July"],

   datasets : [{

       strokeColor : "rgba(220,220,220,1)",

       data : [65,59,90,81,56,55,40]

   },{

       strokeColor : "rgba(151,187,205,1)",

       data : [28,48,40,19,96,27,100]

   }]

};

 

//  Serialize to valuetree

var tVT = df.sys.vt.serialize(oData);

 

//  Send call to the server

this.serverAction("ProcessData", [ 2, 1 ], tVT, function(oEvent){

    alert(oEvent.sReturnValue);

});

In the example above the oData object is serialized into a valuetree stored in the tVT variable. This value tree is passed to the server as the aOptData parameter of the serverAction method.

//  Define the structs

Struct tActionDataSet

    String strokeColor

    Integer[] data

End_Struct

 

Struct tActionData

    String[] labels

    tActionDataSet[] datasets

End_Struct

 

//  Function called as server action

Function ProcessData Integer iParam1 Integer iParam2 Returns String

    tWebValueTree tVT

    tActionData tData

    

    //  Retrieve and deserialize data

    Get ptActionData to tVT

    ValueTreeDeserializeParameter tVT to tData

    

    Function_Return tData.labels[3]

End_Function

 

WebPublishFunction ProcessData

The DataFlex code above defines structs that match the format of the data sent by the client. Then the ProcessData function is defined which retrieves the value tree from the ptActionData property (that is where the WebApp Framework puts it). It deserializes the data into the struct format using the ValueTreeDeserializeParameter command. Now the data can be accessed like a regular struct / array.

 

Events

The framework has some special standardized support for events. Events are basically server actions that are meant implemented by the developer using the control. So usually that would be done in the object instead of the class. The server-side event handler can be turned off using a web property for efficiency reasons and optionally the event can be implemented on the client. A web property can be set to the name of a global JavaScript function that will handle the event.

In the DataFlex class an event is defined by two web properties and a published stub procedure. The example below shows how to define an event named OnIncrement. Note that the procedure is marked as event using a meta tag so that the studio will thread it as an event. In this case the event is enabled by default.

Procedure Construct_Object

    Forward Send Construct_Object

    //  OnIncrement event properties

    { WebProperty=True }

    Property Boolean pbServerOnIncrement True

    { WebProperty=True }

    Property String psClientOnIncrement ""

    

    //  Set client-side class

    Set psJSClass to "Spinner"

End_Procedure

 

{ MethodType=Event }

Procedure OnIncrement Integer iNewValue Integer iPrevValue

    //  Empty event stub

End_Procedure

 

Procedure End_Construct_Object

    Forward Send End_Construct_Object

    

    //  Publish functions called from the client

    WebPublishProcedure OnIncrement

End_Procedure

On the client the event is defined in the constructor function using the event function available on df.WebObject. This function defines the properties and creates a df.events.JSHandler object for advanced client-side event handling. Then the event is fired using the fire function.

this.event("OnIncrement", df.cCallModeWait);

this.fire("OnIncrement", [ this.piSpinValue, iPrevValue ], function(){

    //  This code is executed after the server processed this event

});

[TODO: Describe call mode]

fire (df.WebObject)

This method is used to trigger an event. It will check if the server-side event is enabled and if the client-side handlers are registered. It returns true if the event is handled on the client or the server.


Parameter

Type

Description

sName

String

Name of the published DataFlex function / procedure.

aParams

Array

Array with the parameters that need to be passed to the function / procedure.

fOptHandler

Function

(optional) Handler function executed when the call is finished and a response is received.

oOptEnv

Object

(optional) Object that will be the context when the handler function is called. The JavaScript this will point to this object. If no object is passed the JavaScript web object itself will become the context.

 

Client Actions

Next to server actions the framework also knows client actions which are basically function calls on the client. Any JavaScript function available on a web object can be called. The ShowInfoBox function is an example of a client action that shows an info box. Lists and Grids also use a client action to fill themselves. In DataFlex the ClientAction procedure on cWebObject is available to perform client actions.

ClientAction (cWebObject)

This method is used to call a JavaScript function on the web object. This function works asynchronous as the call is queued and added to the response.


Parameter

Type

Description

sName

String

The name of the JavaScript function.

aOptParams

String[]

Array with the parameters that need to be passed to the function.

aOptData

tWebValueTree

(optional) tWebValueTree struct that can be used to send additional complex data.

 

Calling a JavaScript Function

The function in JavaScript is just a regular function and no extra publishing is required. The example below shows a function that shows a standard info box in the browser using the window.alert API.

sayHello : function(sTo, sFrom){

    window.alert(sFrom + " says hi to " + sTo);

},

The sample below shows how to call this function from the server-side object using the ClientAction procedure.

String[] aParams

Move "the World" to aParams[0]

Move "John" to aParams[1]

Send ClientAction "sayHello" aParams

 

Passing Complex Data

Similar to server actions it is also possible to complex sets of data to client actions. This is also done using the tWebValueTree format. The value tree can be passed as the third parameter of the ClientAction procedure.

//  Define the structs

Struct tActionDataSet

    String strokeColor

    Integer[] data

End_Struct

 

Struct tActionData

    String[] labels

    tActionDataSet[] datasets

End_Struct

 

//  Send the client action

String[] aParams

tWebValueTree tVT

tActionData tData

 

//  Generate some data

Move "Januari"      to tData.labels[0]

Move "Februari"     to tData.labels[1]

Move "#FF0000"      to tData.datasets[0].strokeColor

Move 55             to tData.datasets[0].data[0]

Move 88             to tData.datasets[0].data[0]

 

//  Serialize to a value tree

ValueTreeSerializeParameter tData to tVT

 

//  Call the client action

Send ClientAction "processData" aParams tVT

The DataFlex code above shows the entire process of defining a struct, filling it and sending it to the client. Note that the ValueTreeSerializeParameter command is used to serialize the struct into a value tree.

//  Define the struct format used by the deserializer

var tActionDataFormat = {

labels : [ df.tString ],

datasets : [{

        strokeColor : df.tString,

        data : [ df.tInt ]

    }]

};

 

//  Client action called with action data

processData : function(){

    var tData, tVT;

    

    // Retrieve value tree and deserialize

    tVT = this._tActionData;

    tData = df.sys.vt.deserialize(tVT, tActionDataFormat);

    

    // Do something with the data

    alert(tData.labels[1]);

},

The sample code above shows how to handle this data in JavaScript. It starts by defining the structure of the data it receives. As the value tree only contains the data the deserializer needs the format to bring the data back to a readable format. The value tree is made available by the framework under the this._tActionData property. We use the df.sys.vt.deserialize function to deserialize the value tree into usable data objects. 

 

Previous Topic: Web Properties

Next Topic: Control Template

 

See Also

Developing Web Applications