4D Ajax Framework Developer Guide
4D Ajax Framework Developer Guide
Developer’s Guide
4th Dimension®
© 1985 - 2007 4D SAS/4D, Inc. All rights reserved.
4D Web 2.0
4D Ajax Framework Developer’s Guide
Copyright© 1985 - 2007 4D SAS / 4D, Inc.
All rights reserved.
The software and the manual are copyrighted and may not be reproduced in whole or in part except for the
personal licensee’s use and solely in accordance with the contractual terms. This includes copying the elec-
tronic media, archiving, or using the software in any manner other than that provided for in the Software
license Agreement.
4D, 4D Draw, 4D Write, 4D Insider, 4th Dimension®, 4D Server and the 4th Dimension and 4D logos are reg-
istered trademarks of 4D S.A.S.
Windows, Windows NT, Windows XP and Microsoft are registered trademarks of Microsoft Corporation.
Apple, Macintosh, Mac OS, Mac OS X, QuickTime are trademarks or registered trademarks of Apple Com-
puter Inc.
Mac2Win Software Copyright © 1990-2007, is a product of Altura Software, Inc.
This product includes software developed by the Apache Software Foundation (http://www.apache.org/).
4th Dimension includes cryptographic software written by Eric Young ([email protected])
4th Dimension includes software written by Tim Hudson ([email protected]).
Spellchecker © Copyright SYNAPSE Développement, Toulouse, France, 1994-2007.
ACROBAT © Copyright 1987-2007 Secret Commercial Adobe Systems Inc. All rights reserved. ACROBAT is a
registered trademark of Adobe Systems Inc.
All other referenced trade names are trademarks, registered trademarks, or copyrights of their respective
holders.
Contents
Developer’s Guide. . . . . . . . . . . . . . . . .5
Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
4D Ajax Framework Concepts . . . . . . . . . . . . . . . . . . . 5
Localization . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Developer Hooks . . . . . . . . . . . . . . . . . . . . . . . 6
Views or Selections . . . . . . . . . . . . . . . . . . . . . . 6
Callbacks. . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Setting Preferences. . . . . . . . . . . . . . . . . . . . . . . . . 7
Language and Interface Settings . . . . . . . . . . . . . . . 7
General Settings . . . . . . . . . . . . . . . . . . . . . . . . 8
Managing User Authentication and Sessions . . . . . . . . . . . 9
Authentication Developer Hooks . . . . . . . . . . . . . . 10
Managing Data Modification . . . . . . . . . . . . . . . . . . 15
DAX_DevHook_SaveRecord . . . . . . . . . . . . . . . . . 15
DAX_DevHook_DeleteRecord . . . . . . . . . . . . . . . . 16
Creating DCS Views . . . . . . . . . . . . . . . . . . . . . . . 17
DAX_DevHook_DCS_ViewAdd . . . . . . . . . . . . . . . 17
DAX_DevHook_DCS_SetSelection . . . . . . . . . . . . . 19
DAX_DevHook_DCS_RecordSave . . . . . . . . . . . . . . 21
DAX_DevHook_DCS_RecordDelete . . . . . . . . . . . . . 23
Creating DDW Views . . . . . . . . . . . . . . . . . . . . . . 24
Creating Callbacks . . . . . . . . . . . . . . . . . . . . . . . . 25
DAX_DevHook_InstallCallBack . . . . . . . . . . . . . . . 26
Method to be executed on a Callback. . . . . . . . . . . . 26
Overview
4D Ajax Framework allows 4D developers to add web browsing
integration into their applications. Using Ajax technology, 4D
developers can offer the end-user a rich web 2.0 interface that can
browse, add, modify and delete records from the underlying database.
4D Ajax Framework includes a component and a full Javascript
framework that is available for integration into existing HTML pages.
Experienced 4D web developers will be able to use the DAX API
(Javascript framework) to quickly add 4D Ajax Framework objects into
their existing HTML/Javascript pages.
The developer can add new language elements by editing the XML file.
For example, if you want the " Ajax Framework Initializing" startup
message to appear in Spanish, simply add a <es> element as a child of
the <DAXInitializing> element with the message in Spanish as the
element value.
■ en_errors.xml
This file contains all of the error messages that are sent to the front
end. By default, the name of the file matches the language value set in
the variable <>DAX_Language_t ("en"). You can create an error file for
another language by duplicating the en_errors.xml file and changing
the contents of the <message> nodes.
Developer Hooks Developer Hooks allow the 4D developer to override certain default
Ajax Framework behaviors and to trap various events. Use of the
Developer Hooks is optional. The only editable methods within the
Ajax Framework component are named DAX_DevHook... The only
callable methods in the Ajax Framework component are named
DAX_Dev_... Use of the various available developer hooks is discussed
later in this document.
Views or Selections A view or selection is a window that displays data or other content to
the user. The simplest example of this is the window that opens and
displays the list of records when a table name is clicked on in the
Portals sidebar. You can create various custom views within the Ajax
Framework component to be added to the list of tables that appears by
default.
Developer Created Developer Created Selections (DCS) are views that are completely array
Selections driven. The developer defines the view through 4D code and provides
arrays with the data that is used in the view. See Creating DCS Views
later in this document for more information.
Developer Defined Developer Defined Windows (DDW) are views that can contain any
Windows HTML content. They are not generally for displaying a list of data but
instead available to display a complete web page within the front-end
user interface. A DDW can open a link to an external site such as
http://www.4d.com or call back to the developer's existing web code
with a link such as /4dcgi/mymethod. A DDW can also be sent an
HTML blob directly. This allows the developer to create a web page in
memory and deliver it to the front-end.
Callbacks Callbacks act similar to 4D's form events. A callback can be assigned to
a field within the input form and call 4D code when a particular event
occurs (currently On Load and On Data Change). For example, an
email address can be validated when a user tabs out of the email
address field and the user can be given immediate feedback if the
address is determined to be invalid. See Creating Callbacks later in this
document.
Setting Preferences
4D Ajax Framework has several global preferences that you can adjust
to your specific needs. To change the default settings, open the project
method DAX_DevHook_Preferences and edit the variable values
defined below.
Language and There are two 4D Ajax Framework language settings. The first setting
Interface Settings determines what language 4D Ajax Framework should use when
displaying information dialogs in the 4D interface during startup and
shutdown. The second determines what language 4D Ajax Framework
uses when displaying information to the front-end (web browser) user
interface.
▼ Example
<>DAX_Language_t:="en" ` set the 4D interface language to English
The language to use for the Ajax Framework front-end can be installed
on a group by group basis. To install a language for a particular group,
make a call to the project method DAX_Dev_InstallLanguage inside
the DAX_DevHook_Preferences method. By default the front-end will
use English for all groups.
▼ Example
DAX_Dev_InstallLanguage ("Admins";"en")
` set the language for Admins to English
DAX_Dev_InstallLanguage ("Group A";"fr")
` set the language for Group A to French
To suppress the startup and shutdown status messages in 4D set the
variable <>DAX_DisplayMessages_b to False. Critical error alerts will
still be displayed.
▼ Example
<>DAX_DisplayMessages_b:=False ` Turn off messages
<>DAX_DisplayMessages_b:=True ` Turn on messages
General Settings There are several general settings 4D Ajax Framework uses in
conjunction with its various features.
▼ Example
<>DAX_LOCK_TIMEOUT_m:=?00:05:00?
` expire locks after 5 minutes of inactivity
When a new view is created from the Admin area of the 4D Ajax
Framework front-end the related tables are displayed so data may be
combined from multiple tables. The number of relations to follow is
set in the variable <>DAX_Rel_DepthLevel_l. By default this value is set
to eight. It is recommended that this value not be increased.
▼ Example
<>DAX_Rel_DepthLevel_l:=8
If you already have your own login system in place, for instance a
Users table, you can hook into the 4D Ajax Framework
implementation and authorize users yourself. If you also have your
own session management system you can hook into the 4D Ajax
Framework session implementation and validate the sessions yourself
as well.
Authentication
Developer Hooks
DAX_DevHook_Login DAX_DevHook_Login is used by the Developer to override the 4D Ajax
Framework login system. By default 4D Ajax Framework uses the 4D
Users and Groups system to authenticate users when they login using
the 4D Ajax Framework login object. If you have your own login
system you can hook into the login process using this method and take
over user validation. If you are using the 4D Ajax Framework login
system (4D Users and Groups) you do not need to modify this method.
Using the system you currently have in place you validate the user
name and password. This most likely involves querying a table for the
user name and password to authenticate the user. If you are using the
4D Ajax Framework login object on the web page you can retrieve the
user name and password using the following calls:
$userName_t:=DAX_Dev_GetWebVar ("username")
$password_t:=DAX_Dev_GetWebVar ("password")
If the user has successfully logged in, you return True from this
method and, if their login fails, you should return False.
Upon Failed Login If the login is not successful, you must pass an error code to Ajax
Framework. If you return False from this method and do not pass an
error code, Ajax Framework will attempt to log the user in. To set a
login error code call DAX_Dev_Session_Error and pass an appropriate
error code.
Using whatever system you currently have in place, you validate the
user's current session. This most likely involves querying a table for the
session id. 4D Ajax Framework supplies the session id with every 4D
Ajax Framework call. You can retrieve the supplied session id with the
following call:
$sessionid_t:=DAX_Dev_GetWebVar ("sessionid")
If the session is valid, return True from this method. If the session is
not valid, return False.
Upon Failed Login If the session is not valid you must pass an error code to 4D Ajax
Framework. If you return False from this method and do not pass an
error code, 4D Ajax Framework will attempt to validate the session
itself. To set a session error code call DAX_Dev_Session_Error and pass
an appropriate error code.
■ Returned:
$0 BOOLEAN - Flag indicating that you are using your own groups system
▼ Example:
$userName_t:=$1
$groupName_t:=$2
$userInGroup_p:=$3
READ ONLY([Users])
READ ONLY([User_Groups])
QUERY([Users];[Users]User_Name=$userName_t)
RELATE ONE([Users]User_Groups_Link)
$userInGroup_p->:=([User_Groups]Group_Name=$groupName_t)
UNLOAD RECORD([Users])
UNLOAD RECORD([User_Groups])
■ Returned:
$0 BOOLEAN - True=OK to save, False=Do not save and send an error
The record is loaded in READ WRITE mode when this method is called,
but the record has not been saved yet. 4D Ajax Framework will expect
the record to be loaded still in READ WRITE mode after this call. If you
need to modify the selection within the table, you must first save the
record and then restore the selection in READ WRITE mode when your
code completes.
The record is loaded in READ WRITE mode when this method is called.
4D Ajax Framework will expect the record to be loaded still in READ
WRITE mode after this call. If you modify the selection within the
table, you must restore the selection in READ WRITE mode when your
code completes. Any code you have in Triggers will execute normally.
When using custom views the developer must handle all of the other
DCS hooks as well:
DAX_DevHook_DCS_SetSelection
DAX_DevHook_DCS_RecordSave
DAX_DevHook_DCS_RecordDelete
You can add as many custom views as you like. Just make one call to
DAX_Dev_DCS_AddCustomView for each view you are adding.
Valid Date Types The following is a list of the valid data types you may use in the types
array. The types serve two purposes. The first is to let 4D Ajax
Framework know what type of value it is working with so it can make
the proper conversions when necessary (using String, Num, Date, etc.).
The second is to let the 4D Ajax Framework web front-end know what
type of display to use for field input. For example, the type 'Is Text' will
cause a multi-line text area input field to be displayed, while the type
'Is String Var' will cause a single line input field. 'Is Date' will cause a
date entry calendar to be displayed. Numerical types will cause the 4D
Ajax Framework front-end to allow only numerical values to be
entered.
The type is for an individual item, so pass standard types not array
types (i.e., don't use 'Text array' instead use 'Is Text').
Is Text
Is String Var
Is Real
Is Integer
Is LongInt
Is Date
Is Time
Is Boolean
Is Picture
▼ Example:
This example creates a view to display Customer names and the totals
from their Invoices. It is assumed we have a Customer table and a
related Invoice table. This example continues in the other DCS method
definitions.
C_TEXT($viewName_t)
C_BOOLEAN($added_b)
C_LONGINT($i)
ARRAY TEXT($names_at;3)
ARRAY LONGINT($types_al;3)
ARRAY BOOLEAN($unique_ab;3)
ARRAY BOOLEAN($mandatory_ab;3)
ARRAY BOOLEAN($nonEnterable_ab;3)
ARRAY BOOLEAN($nonModifiable_ab;3)
$viewName_t:="Customer Invoices"
` set the name of the view you are adding
When referring to a "record," we mean any single set of data and not
necessarily a record from a 4D table. A record can come from any data
source as long as you can identify it uniquely.
Whatever method you use, the record ID must be a value that can find
and load a particular record (data set) regardless of the current
selection. Using a simple array element number system is not
recommended and would most likely cause serious problems in a
multi-user database.
In other words, if the first element in the column names was "First
Name" the first data array passed should be the one that contains first
names. The type of arrays must be compatible with the types you set
for the columns in DAX_DevHook_DCS_ViewAdd. Compatible means
direct assignment between values is possible. So if you passed a type of
'Is Real' you cannot now pass a text array, but you can pass a longint or
integer array. similarly, if you set the column type to 'Is Text' or 'Is
String var' you can pass a text or string array interchangeably
(assuming the string is long enough to hold your values).
▼ Example:
This example continues from the example view that was created in
DAX_DevHook_DCS_ViewAdd to display Customer names and the
totals from their Invoices. This example continues in the other DCS
method definitions.
Case of
:($viewName_t="Customer Invoices")
` Declare the arrays
ARRAY LONGINT(recordIDs_al;0)
ARRAY REAL(totals_ar;0)
ARRAY TEXT(firstNames_at;0)
ARRAY TEXT(lastNames_at;0)
` Set the selection in DAX in the order defined when we created the View
DAX_Dev_DCS_SetSelection(->recordIDs_al;->firstNames_at;
->lastNames_at;->totals_ar)
End case
If you save the record, return the record id, either the same one that
was passed in (for modifying) or a new record id (for new records). If
you do not save the record, return the constant 'No current record'.
■ Passed:
$1 TEXT - Name of the DCS View where the record is being saved
$2 LONGINT - Record ID for the record that is being saved ('New record'
constant for new records)
$3 POINTER - Pointer to text array of field names for the record that is
being saved
$4 POINTER - Pointer to text array of field values for the record that is
being saved
■ Returned:
$0 LONGINT - Record ID for the record (either same as passed, ID for new
record, or 'No record loaded')
In the case of the ID being a record number, you can use Goto Record
to load the record that needs to be updated. In the case of the ID being
a unique sequence number from an ID field, you can query for the
record that needs to be updated. In other cases it will depend on what
the ID means to you as the developer.
▼ Example:
This example continues from the example view that was created in
DAX_DevHook_DCS_ViewAdd to display Customer names and the
totals from their Invoices. This example continues in the other DCS
methods.
Case of
:($viewName_t="Customer Invoices")
If($recordNumber_l=New record)
CREATE RECORD([Invoice])
QUERY([Customer];[Customer]FirstName=$firstName_t;*)
QUERY([Customer]; & ;[Customer]LastName=$lastName_t)
[Invoice]CustomerID:=[Customer]ID
Else
READ WRITE([Invoice])
GOTO RECORD([Invoice];$recordNumber_l)
If(Records in selection([Invoice])#1)
$recordNumber_l:=No current record
UNLOAD RECORD([Invoice])
End if
End if
End case
$0:=$recordNumber_l
In the case of the id being a record number, you can use Goto Record
and delete the record. In the case of the id being a unique sequence
number from an id field, you can query for the record and delete the
record. In other cases it will depend on what the id means to you as
the developer.
▼ Example:
This example continues from the example view that was created in
DAX_DevHook_DCS_ViewAdd to display Customer names and the
totals from their Invoices. This example continues in the other DCS
methods.
$deleteRecordAccepted_b:=True
Case of
:($viewName_t="Customer Invoices")
If ($recordID_l>No current record )
READ WRITE([Invoice])
GOTO RECORD([Invoice];$recordID_l)
End if
If (Records in selection([Invoice])=1)
DELETE RECORD([Invoice])
Else
$deleteRecordAccepted_b:=False
UNLOAD RECORD([Invoice])
End if
End case
$0:=$deleteRecordAccepted_b
A DDW can be created at the portal level, selection level or field level.
A portal level DDW is displayed in the left sidebar of the main window.
A selection level DDW is displayed at the top of a window which
displays a selection of records with the Create, Delete, etc. buttons. For
selection level a button is also added to the detail view next to the Save
and Cancel buttons. A field level DDW causes the field data to display
as a link in a list of records and as a button next to the field value in
the detail views
4 Associated To as Text. This is the type of object with which the DDW
will be used. Valid values are "Portal" or "Other". This parameter is
optional and will default to "Other" if it is not provided.
▼ Examples:
You can add as many DDW views as you like. Just make one call to
DAX_Dev_DDW_Create for each DDW view you are adding.
■ Adding a Portal
$ddwID_l:=DAX_Dev_DDW_Create ("Linkstatic";"4D Home Page";
"http://www.4d.com/";"Portal")
■ Creating a DDW and assigning it to multiple fields
$ddwID_l:=DAX_Dev_DDW_Create ("Linkstatic";"Help";"MyHelpMethod")
DAX_Dev_DDW_AssignToObject ($ddwID_l;"Selection";
Table name(->[Contact]))
Creating Callbacks
Callbacks are a way for 4D to respond to certain events that occur in a
field on the front-end. When an event is triggered, the front-end will
post the event information and field value to the 4D. 4D will then
execute the method that is set to handle the event and return a
response back to the front-end. Currently 4D Ajax Framework supports
two events from the front-end: On Load (event id=1) and On Data
Change (event id=20).
1 On Load - The field object is about to be drawn in the Detail View.
2 On Data Change - The user tabbed out of the field.
Method to be The method that is set to respond to a callback must return a Text
executed on a value in $0 to be used as the new value for the field that triggered the
Callback event. 4D Ajax Framework callback methods have access to six
attributes when they run:
1 Event ID as Longint. This is the event that triggered the callback.
2 Table ID as Longint. This is the table number for the edited field.
3 Table Name as Text. This is the table name for the edited field.
4 Field ID as Longint. This is the field number for the edited field.
5 Field Name as Text. This is the field name for the edited field.
6 Record ID as Longint. This is the record number (-3 for new records).
7 Value as Text. This is the value the user entered for the edited field.
8 Message as Text. Text message that will be returned to the front-end.