Ajax Callback

Description

Define a user-defined ajax callback. The callback can be handled by an Xbasic function that is defined in the component, by a separate .a5w page, or by another page (.e.g., .php, .asp, etc.)

Discussion

The Ajax Callback Action Javascript can be used to generate the Xbasic callback function that is called. The Xbasic callback function can be saved in the component in the Xbasic Functions section of the component builder. The action can be accessed anywhere the Action Javascript editor is available, including Javascript events for controls and Javascript Actions.

Ajax Callback Properties 

Submit data

Specify if data from the grid should be submitted to the server when the callback is made.

Data from the current row are only submitted for fields that are editable. Primary key values, however, are submitted regardless of whether the current row is editable or not.

Submit part

Specify the part from which data should be submitted. Choices include.

Row number

Specify which row in the grid to submit data from. The {Grid.Rownumber} placeholder is used to indicate the 'current row' in the Grid. To submit data from ALL of the rows in the grid, set Row Number to: All. To specify a new record row, use a negative number. e.g. -1 for the first new record row, -2 for the second new record row, etc.

Callback type

Specify the callback type. The callback can be handled by a Xbasic function, or by a page referenced by a URL. The function can be defined in the Grid (see 'Xbasic function declarations' section of the Grid), or in an .AEX file. Choices include.

Function name

Specify the Xbasic function name (do NOT include '()' in the name. e.g. specify name as 'myFunction', not 'myFunction()' ). The Xbasic function prototype must be: function functionName as c (e as p). The function must return Javascript code that you want to execute on the client. The 'e' parameter that is passed into the function contains all of the data submitted to the server on the callback.

Use the Firebug add-in for Firefox to see what data is submitted on the callback.

Click 'Create function prototype' for an example of the required syntax for the function.

URL

Specify the URL of the page that will handle the callback.

Action name

A variable called '_action' is passed to the URL. The value of _action is set to Action Name.

Advanced Properties 

Additional data to submit

Specify any additional data that you want to submit to the server. This data must be in the form of a URL parameters string (i.e. name/value pairs) and it must be enclosed in single quotes. For example '_var1=alpha&_var2=beta'

TIP: The 'Additional data' can be computed by a Javascript function call. For example, you might have defined a Javascript function called 'gatherInfo'. If you specify 'gatherInfo()' here (without single quotes), the value returned by this function will be included in the data sent back to the server as part of the Ajax callback.

Compute current row data

If the current row is not editable, and the 'Submit Data' property is checked, field values from the current row are not submitted. Only the primary key values for the current row are submitted. However, if you check this box, then the server will query the database to retrieve the field values for the current row and make these values available to your callback handler.

IMPORTANT: To use this option in a read-only Grid based on SQL tables, you must ensure that you have defined the Primary Key for each table.

After callback complete Javascript

Specify any Javascript you want to execute when the callback is complete and all of the Javascript returned by the callback (if any) has executed.

The 'After callback complete Javascript' property.

A Note on the 'After callback complete Javascript' Property 

To specify the after callback complete Javascript in the UX or Grid's .ajaxCallback() method, you set the onComplete property in the optional optionsObject passed in. For example:

{dialog.object}.ajaxCallback('','','myXbasicFunction','','',{onComplete: function() { 
        alert('callback is complete')
    }
})

Location Data Properties 

Submit location information

Specify if location information (longitude/latitude) should be submitted. The location information is obtained from the browser. The user will be prompted for permission to read location information. Not all browsers support retrieving location information.

The 'e' object passed to the Xbasic function will contain these properties:

__locationFound

true/false

__locationLatitude

the latitude value

__locationLongitude

the longitude value

High accuracy

If true, the device will use its most accurate method to get location information. If false, the device will use its fastest or lower power consumption method depending on the device.

Timeout

The amount of time in milliseconds to wait on the device to acquire location information excluding the amount of time it takes the user to grant the web page access to geolocation data.

Max age

The amount of time in milliseconds to accept a previously acquired location. 0 means that a new location must be acquired from the device.

Ajax Failed/Offline Javascript Properties 

If the Ajax Callback fails because the client's device is online, these properties can be used to do fall-back processing -- such as notify the user that no network connection is available and that they should try again when they're connected to the Internet.

These properties are optional.

Timeout setting

Specify the time to wait (in milliseconds) for a response from the callback. If a response is not received within the specified time, the callback is considered to have failed and the 'onAjaxCallbackFailed' client-side event will be fired, and any Javascript defined in the optional 'Ajax failed Javascript' property will be executed. If you specify '<Default>' the global default value (defined in the {dialog.object}.ajaxCallbackTimeout property) will be used.

Ajax failed Javascript

Specify the Javascript to execute if the Ajax callback fails (i.e. if the server does not send a response).

Offline Javascript

Specify the Javascript to execute if the device is offline. Since the device is offline, the Ajax callback is not made. Therefore the code in the 'Ajax failed Javascript' property will not get executed.

Chunked Responses 

When an Ajax Callback is made, the user will not receive a response until the callback completes -- or a timeout is reached and the client gives up waiting for a response. Long-running processes can have the appearance of a browser hang if the user is unaware that the action they've performed will take a while. In this situation, you may want to send periodic updates to the user notifying them that the process is still running.

You can send intermediate responses from the Xbasic function to the client by enabling "Chunked Responses". A "Chunked Response" is a message sent from the Ajax Callback function to the client while the function continues to execute.

To enable chunked responses from your Ajax Callback, check the Allow chunked responses property.

In order to use chunked responses on IIS or Alpha Cloud, you must enable JIT Sessions. On Alpha Cloud, the JIT Sessions option is available in the Deployment dialog.

Enabling Allow chunked responses exposes the following properties:

Property
Description
Maximum number of messages

The maximum number of chunked responses that the client will handled. Set to -1 for no limit. Default is -1.

Maximum duration for callback

Set the maximum amount of time (in seconds) to allow for the callback function to complete processing. If your function takes longer than the specified time, the callback is terminated and any additional messages set to the client are ignored.

To send intermediate messages from your Ajax Callback function, use the a5AjaxChunkedResponseWrite() function. The a5AjaxChunkedResponseWrite() function takes one parameter -- a string that contains JavaScript to execute on the client. For example:

DIM js AS C
js = "$('div').innerHTML = 'Still working...';"
a5AjaxChunkedResponseWrite(js)

To learn more, download the example component and watch the video, "Chunked Responses - Sending Intermediate Responses to the Client", in the Videos section below.

Using Action Javascript to Write an Ajax Callback Function 

  1. In the event editor with Action Javascript mode selected, click the Add button to add a new action.

  2. Select the Ajax Callback action and click OK.

  3. Define the name for the callback function that will be called. In the image below, a new function will be created that performs the callback called myCallback

  4. Define any additional (optional) data to submit to the callback function. Parameters sent to the callback function can be accessed through the e object in the Xbasic function.

  5. Click the Create function prototype link to generate the function prototype for the Ajax callback.

  6. Click the Copy to clipboard button to copy the function signature to the clipboard. When the code has been copied to the clipboard, click the Close button to close the dialog.

  7. Click the Open Xbasic Function Declarations link to open the Xbasic Function Declarations dialog. This is a shortcut to the Xbasic Functions section.

  8. Paste the code from the clipboard into the window and click OK.

  9. Click OK to save the Ajax Callback action.

  10. Optionally, add a comment that describes the action when prompted. Then, click the OK button.

  11. Click the Save button to save the changes made to the event or Javascript Action.

  12. Navigate back to the component builder. Expand the Code section in the far left column and click on Xbasic functions. This is where you can make changes to the Xbasic callback function you created using the Ajax Callback Action Javascript builder.

Making Callbacks from Javascript 

It's best to use Action Javascript if it's available to add functionality to an application. If you would rather make a callback using Javascript, however, the .ajaxCallback() method for the Grid or UX Component is available. To learn more, visit the Grid Component or UX Component Client API documentation for the .ajaxCallback() method.

Variables Passed to the Xbasic Callback Function 

The Xbasic function that handles the callback will be passed a dot variable called e with the following properties:

tmpl

The component definition.

__si

Component state information passed between the server and client.

rtc

Runtime calculations computed while the component is executing.

dataSubmitted

A pointer variable that contains the data values submitted to the callback.

oldDataSubmitted

A pointer variable that contains the original values for controls in the UX.

listInfoJSON

If the UX Component contains one or more List controls, contains an array of objects in JSON format with information about the list. Each entry in the array has the following format:

{"list":"listId","checkedRows":"comma_delimited_list_of_checked_rows"}

"list" contains the ID of the List control. If the List has a check-box select column, "checkedRows" is a comma delimited list of rows that have been checked.

You can inspect the JSON to determine what rows are checked in a List with a check-box select control. For example:

DIM listInfo AS P
listInfo = json_parse(e.listInfoJSON)

if (listInfo.size() > 0) then
    if (variable_exists("listInfo[1].checkedRows")) then
        DIM listId AS C
        DIM rows AS C
        listId = listInfo[1].list
        rows = crlf_to_comma(listInfo[1].checkedRows.dump_properties(" value"))
        ' Return JS alert displaying the list of checked rows for the first list in listInfo.
        e.javascript = "alert('Checked rows for list \'"+listId+"\' : "+rows+"');"
    end if
end if

If a list has no checked rows, the checkedRows property will be blank.

repeatingSectionNames

If the UX contains one or more repeating sections, contains a comma delimited list of container IDs for each repeating section.

repeatingSectionInfo

If the UX contains one or more repeating sections, contains a property array with one entry for each repeating section with the following properties:

activeRow

The repeating section row that had focus with the callback was made.

deletedRows

A CRLF delimited list of delete rows in the repeating section.

rowCount

The number of non-deleted rows in the repeating section.

totalRowCount

The total number of rows in the repeating section -- includes deleted rows.

fieldsInRepeating

A CRLF delimited list of fields in the repeating section.

dirtyRowsInSection

A CRLF delimited list of modified rows in the repeating section.

dirtyFieldsInSection

A CRLF delimited list of modified fields in the repeating section. Each field uses the following format:

fieldname_A5INSTANCErownum

Where fieldname is the name of the field name and rownum is the row number in the repeating section. For example, if the 'PARTNO' field for row 3 in a repeating section has been modified, the following entry will be in the dirtyFieldsInSection list:

PARTNO_A5INSTANCE3
_set

An optional variable that can be used to set the value or select properties of a control on the client. Alpha Anywhere generates the required JavaScript to send to the client to set the value or property. For example:

' Set the value of 'Lastname'
e._set.lastname.value = "Smith"

'Set the value in 3rd Repeating Section row
e._set.firstname_a5instance3.value = "Fred"

' Set the style attribute for the 'Lastname' field
e._set.lastname.style = "color: red;"

' Set the class attribute for the 'Lastname' field
e._set.lastname.className = "NewClassName"

' Set the color and font size of the 'Firstname' field
e._set.firstname.style.color = "red"
e._set.firstname.style.fontSize = "20pt"

' Set multiple values in a checkbox or dropdown:
DIM choices AS P          ' declare a pointer variable
DIM choices.value[3] AS C ' add a property called 'value'
choices.value[1] = "alpha"
choices.value[2] = "beta"
choices.value[3] = "gamma"
e._set.greekletters.value = choices

Setting style attributes preserves any existing styling. It is important to note that attribute names are case-sensitive.

Using _set to return JavaScript can have a negative impact on performance. Prefer to return JavaScript directly from your Xbasic function. EG:

DIM js AS C = ""
js = js + "{dialog.object}.setValue('LASTNAME','Smith');"
js = js + <<%js%
var ele = {dialog.object}.getPointer('FIRSTNAME'); 
if (ele) { 
    ele.style.fontSize = '20pt'; 
    ele.style.color = 'red';
}
%js%

' Return JavaScript from the callback and terminate the function:
return js
_setElement

Similar to the _set property, an optional variable that can be used to set the value or select properties of an element, such as DIV or SPAN. Alpha Anywhere generates the required JavaScript to send to the client to set the value or property. For example:

' Set the innerHTML of DIV with the id of 'DIV1' 
e._setElement.DIV1.value = "Some text"
' Set style properties of a SPAN with id of 'SPN2'
e._setElement.SPN2.style.color = "Red"

Setting style attributes preserves any existing styling. It is important to note that attribute names are case-sensitive.

Using _setElement to return JavaScript can have a negative impact on performance. Prefer to return JavaScript directly from your Xbasic function. EG:

DIM js AS C = ""
js = js + "$('DIV1').innerHTML = 'Some text';"
js = js + <<%js%
var ele = $('SPN2');
if (ele) { 
    ele.style.color = 'red';
}
%js%

' Return JavaScript from the callback and terminate the function
return js

Videos 

Chunked Responses - Sending Intermediate Responses to the Client

Normally, when you make an Ajax callback from a UX component, the Xbasic function that handles the callback completes its processing and then returns Javascript to the client. In some uses cases where your Xbasic function takes a "long" time to execute, you might want to send some type of intermediate message to the client telling them that the function is still processing and perhaps letting the user know what stage the function is at.

In order to send back intermediate responses to the client while the Xbasic function is still processing, you can set the Ajax callback to allow chunked responses.

In this video we show how you can configure an Xbasic function to do chunked responses.

Download Component

2019-05-02

See Also