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.
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.
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) Complex data such as a struct. 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. |
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);
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. This can be done by passing your complex data as the third parameter in the serverAction function .
The example below shows how to add a complex set of data to a server action.
// Create data objects
const 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]
}]
};
// Send call to the server
this.serverAction("ProcessData", [ 2, 1 ], oData, function(oEvent){
alert(oEvent.sReturnValue);
});
In the example above, the oData object 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
tActionData tData
Handle hoJson
// Retrieve and deserialize data
Get phoActionJsonData to hoJson
Get JsonToDataType of hoJson 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, which retrieves the data from the phoActionJsonData property (that is where the WebApp Framework puts it), is defined. It deserializes the data into the struct format using the JsonToDataType command. Now the data can be accessed like a regular struct / array.
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
});
cCallModeDefault: send the request, don't wait for the reply - allow WebApp to continue to be used.
cCallModeWait: Send the request, wait for a reply from the server. This locks the WebApp at the client.
cCallModeProgress: Same as wait, but shows a little "loading" dialog with an optional message and a progress that you can incrementally update.
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. |
In addition 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.
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 |
Variant |
(optional) Variant that can be used to send additional complex data. |
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(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
Similar to server actions it is also possible to complex sets of data to client actions. The complex data 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
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]
// Call the client action
Send ClientAction "processData" aParams tData
The DataFlex code above shows the entire process of defining a struct, filling it and sending it to the client.
// Client action called with action data
processData(){
let tData;
// Retrieve the data
tData = this._tActionData;
// Do something with the data
alert(tData.labels[1]);
},
The sample code above shows how to handle this data in JavaScript. The data is made available by the framework under the this._tActionData property.
Previous Topic: Web Properties
Next Topic: Control Template