form
The form class is intended to be called as a delegate by a form controller class, as in the code example below line 8.
Hierarchy
Example
// Class _myDialog_Controller
Class constructor
This.isSubform:=False
This.toBeInitialized:=False
// Instantiate the form
This.form:=cs.form.new(This)
...
This.form.init()
Function init()
// Instantiate the widgets we want to manipulate.
This.box:=This.form.Input("Input")
This.ok:=This.form.Button("Button")
This.cancel:=This.form.Button("Button1")
// Resize the window
This.form.window.setRect(400; 600)
// Set window title
This.form.window.title:="Passkey"
...
Function onLoad()
...
This.form.update()
Function handleEvents($e:cs.evt)
...
Function update()
<hr>
📌 Note: to simplify the distinction between form objects and object type, this documentation uses the term “widget” for all form objects, whether static (a line, a rectangle…) or not (a button, a subform…).
cs.form.new()
cs.form.new ( parent : 4D.class) : cs.form
cs.form.new ( parent : 4D.class ; form : Object) : cs.form
| Parameter | Type | Description | |
|---|---|---|---|
| Parent | Object | → | form controller class instance |
| form | Object | → | form object definition |
| result | cs.form | ← | New cs.form |
Description
cs.form.new() creates & returns a new instance of the class.
- If the class is included in your project, the constructor automatically retrieves the form definition.
- If the class is issued from a component, the class has no access to the form definition of the host database. In this case, if you want to be sure of accessing all properties and functions, call the delegate instantiation by replacing the line 8 with:
This.form:=cs.form.new(This; Try(JSON Parse(File("/SOURCES/Forms/"+Current form name+"/form.4DForm").getText())))
Table of Contents
- Properties
- Form objects instantiation functions
- Standard suite functions
- Navigation
- Timer
- Focus
- Events
- Associated Worker
- Calls
- Dimensions & resizing
- Color scheme
- Subforms
- Drag & Drop
- Cursor
- Miscellaneous
- Form definition access
General Properties
📌 Other properties are described below in the section devoted to them.
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .name | Current form name | Text |
x | |
| .isSubform | Is the form used as a subform * | Boolean |
False | ✓ |
| .toBeInitialized | Has the form been initialized * | Boolean |
True | ✓ |
| .window | Current form window class object | cs.window |
x | |
| .constraints | The constraints manager | cs.constraints |
x | |
| .fluentUI | Windows theme compatibility flag (True when Fluent UI is active) | Boolean |
False | ✓ |
* To be set up by the form controller class
Form widget instantiation functions
In the form controller class, you instantiate the widgets (form objects) you wish to manipulate (i.e. activate, deactivate, move, set a value, color, etc.) using the form.<Type>(<name>) instantiation functions listed in the table below. See the code sample above, lines 16 to 18.
🚨 Please note that the names of these functions start with a capital letter. For backward compatibility reasons, the same functions, without capital, letters are still defined, but should no longer be used, as they may be deleted in the future. If you are concerned, please take time to replace the lines like:
This.form.<type>.new(“name”)
by
This.form.<Type>(“name”).
| Functions | |
|---|---|
.Button (name: Text) → cs.button |
for a Button, a Check Box or a Radio Button |
.ComboBox (name: Text {; data : Object}) → cs.comboBox |
for a Combo Box |
.DropDown (name: Text {; data : Object}) → cs.dropDown |
for a Drop-down List |
.HList (name: Text {; ref : Integer}) → cs.hList |
for a Hierarchical List |
.Input (name: Text) → cs.input |
for an Input |
.Listbox (name: Text) → cs.listbox |
for a List Box |
.Picture (name: Text) → cs.picture |
for a Static Picture |
.Static (name: Text) → cs.static |
for a Shapes or static widgets like Group Box |
.Stepper (name: Text) → cs.stepper |
for a Stepper |
.Subform (name: Text) → cs.subform |
for a Subform |
.TabControl (name: Text {; data : Object}) → cs.tabControl |
for a Tab Control |
.Thermometer (name: Text) → cs.thermometer |
for a Progress Indicator |
.WebArea (name: Text) → cs.webArea |
for a Web Area |
In addition, other handler can be instantiated. For example: a Group allows you to manage several widgets at once, since groups created in design mode cannot be manipulated at runtime.
| Functions | |
|---|---|
.Group ({name: Text}) → cs.group |
to manage several widgets at once |
.Selector (name: Text) → cs.selector |
a superclass to manage Dropdown, Combo Box and Tab Control widgets |
.Scrollable (name: Text) → cs.scrollable |
a superclass to manage widgets that accept scrollbars |
.Widget.new (name: Text) → cs.widget |
a superclass to manage all active form widgets |
📌 The
nameparameter is the object name as defined in the form editor.
Each instantiated form object inherits all the properties and functions of its class as you can see in each class documentation.
Standard suite functions
📌 The functions listed in the table below represent the standard suite. They must be defined in the
form controller classif you need them, otherwise an alert will be raised if you call one without having defined it.
In the code sample above, line 12, the This.form.init() call explicitly describes that we want to initialize the form, but the initialization code is specific to the form and must therefore be in the class that drives it. This is the role of the Function init() function at line 14.
The formMethod method must be declared as the form method of all forms that are managed in this way. This method initializes the class associated with the dialog, which should be called _<dialogName>_Controller, and calls its handleEvents() function when a form event is generated. The handleEvents() function is therefore part of the standard suite and must be defined in the class associated with the dialog (line 34 of the code sample above).
| Functions | |
|---|---|
| .init() | to initialize the dialog |
| .handleEvents() | to manage form events or form objects |
| .onLoad() | to perform initializations when loading the form |
| .update() | to update the user interface |
| .onOutsideCall() | to manage a call performed with POST OUTSIDE CALL |
| .saveContext() | to save the state of a form when it is unloaded, so that it can be restored when it is reloaded |
| .restoreContext() | to restore the context when the form is reloaded |
| .onBoundVariableChange() | for subforms |
The minimum suite (init(), onLoad(), handleEvents()) is presented in DEMO_1 into the test UI project of the repository. The other demonstrations introduce the use of the suite’s other functions.
Navigation
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .pageNumber | Number of pages in the form | Integer |
x | |
| .page | Current page number | Integer |
x | |
| .pages | A hashmap table* for naming form pages | Object |
{Page_1: 1, Page_2: 2, … , Page_N: N} |
✓ |
📌 The navigation functions apply by default to the current form. So if it’s a sub-form, it’s the sub-form’s page that will be modified, unless you pass the optional
parentparameter where allowed.
| Functions | Action |
|---|---|
.setPageNames (names: Collection) |
Defines the hashmap table* from the collection of names passed |
.pageFromName (name: Text) : Integer |
Returns a page number from its name |
.goToPage (page: Integer| Text {; parent : Boolean}) |
Replaces the currently displayed form page with the form page specified by its page number or name. |
.firstPage ({parent: Boolean}) |
Changes the currently displayed form page to the first form page |
.lastPage ({parent: Boolean}) |
Changes the currently displayed form page to the last form page |
.nextPage ({parent: Boolean}) |
Changes the currently displayed form page to the next form page |
.previousPage ({parent: Boolean}) |
Changes the currently displayed form page to the previous form page |
* The hashmap table allows navigation commands to access a page by its name instead of its page number.
Timer
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .deferedTimer | The last registered deffered action ID | Integer |
✓ |
| Functions | Action |
|---|---|
.setTimer ({tickCount: Integer}) |
Starts a timer and sets its delay, ASAP if tickCount is omitted |
| .stopTimer () | Disables the timer |
| .refresh () | Starts a timer to be executed as quickly as possible |
.deferTimer (id : Integer; tickCount : Integer) |
Registers the ID of an action to be executed in the next timer cycle & launch timer ASAP or after tickCount parameter |
| .clearDeferedTimer () | Remove all registered deffered actions and stop the timer |
Focus
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .focused | Name of the object that has the focus in the form | Text |
x | |
| .entryOrder | Entry order of the current form for the current process | Collection |
[ ] | x |
| .highlight | Text currently selected, if applicable | Text |
x |
| Functions | Action |
|---|---|
| .focus ( widget ) | Gives the focus to a widget. widget can be a widget name or a widget object |
| .removeFocus () | Removes any focus in the current form |
| .focusNext () | Go to next focusable widget |
| .focusPrevious () | Go to previous focusable widget |
.setEntryOrder (names: Collection) |
Sets the entry order of the current form for the current process |
Events
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .events | Form event codes | Collection |
Initialy populated according to the events activated for the form & the form objects | x |
| Functions | Action |
|---|---|
.setEvents (events: Integer|Collection) |
Define the event(s) for the current form |
.appendEvents (events: Integer|Collection) |
Adds form event(s) for the current form |
.removeEvents (events: Integer|Collection) |
Removes form event(s) for the current form |
.postKeyDown (keyCode: Integer {; modifier: Integer }) |
Posts a keyboard event |
Associated Worker
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .worker | Name or ID of the associated worker | Text|Integer |
Null | ✓ |
| Functions | Action |
|---|---|
.callWorker (method: Text).callWorker (method: Text;param: Collection).callWorker (method: Text;param;…; paramN) |
Assigns a task to the associated worker |
Calls
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .callback | Current callback method’s name | Text |
“formCallBack” | ✓ |
| Functions | Action |
|---|---|
| .callMeBack () .callMeBack (param: Collection).callMeBack (param; … ; paramN) |
Call the form using the current callback method |
.callMe (method: Text).callMe (method: Text; param: Collection).callMe (method: Text; param; … ; i) |
Call the form with the passed method |
.callChild (subform: Object|Text; method: Text).callChild (subform: Object|Text; method: Text; param: Collection).callChild (subform: Object|Text; method: Text; param; … ; paramN) |
Executes a project method in the context of a subform (without returned value) |
.spreadToChilds (message : Object{; subforms : Collection}) |
Execute the message.method into all the subforms of the current forms |
.callParent (eventCode: Integer) |
Sends an event to the subform container |
Dimensions & resizing
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .rect | Form dimensions as an object {width,height} |
Object |
x | |
| .horizontallyResizable | Can the form be resized horizontally | Boolean |
✓ | |
| .minWidth | The smallest form width allowed (pixels) | Integer |
✓ | |
| .maxWidth | The largest form width allowed (pixels) | Integer |
✓ | |
| .verticallyResizable | Can the form be resized vertically | Boolean |
✓ | |
| .minHeight | The smallest form height allowed (pixels) | Integer |
✓ | |
| .maxHeight | The largest form height allowed (pixels) | Integer |
✓ |
| Functions | Action |
|---|---|
.setHorizontalResising (resizable: Boolean {; min: Integer {; max: Integer}}) |
Change the form horizontal resizing properties |
.setVerticalResising (resizable: Boolean {; min: Integer {; max: Integer}}) |
Change the form vertical resizing properties |
Color scheme
| Properties | Description | Type | default | Writable |
|---|---|---|---|---|
| .colorScheme | Name of the last updated color scheme | Text |
x | |
| .darkScheme | Is the current color scheme “dark” | Boolean |
x | |
| .lightScheme | Is the current color scheme “light” | Boolean |
x | |
| .resourceScheme | Returns the current scheme suffix | Boolean |
x | |
| .darkSuffix | Suffix used to select the appropriate resource according to the color scheme | Text |
“_dark” | ✓ |
| Functions | Action |
|---|---|
.resourceFromScheme (path: Text) → Text |
Returns the access path to the given resource path with the dark suffix, if applicable |
Subforms
| Properties* | Description | Type | default | Writable |
|---|---|---|---|---|
| .container | The container class object | Object |
x | |
| .containerName | The name of the container | Text |
x | |
| .containerValue | Value of the container | Variant |
✓ | |
| .containerInstance | The container instance | Object |
x |
* Reading these properties when
isSubform= False, generates an error.
| Functions* | Action |
|---|---|
.setContainerValue (value: Variant) |
Sets the container value |
.getContainerValue () → Variant |
Returns the container value |
.callParent (eventCode: Integer) |
Sends an event to the subform container |
* Calling these functions when
isSubform= False, generates an error.
Drag & Drop
| Functions | Action |
|---|---|
.beginDrag (uri: Text; data: Variant {; icon: Picture}) |
Appends data to the pasteboard under the data type specified in uri.Also sets the drag icon if passed |
.getPasteboard (uri: Text) → Variant |
Returns the data from the pasteboard whose type you pass in uri |
Cursor
| Functions | Action |
|---|---|
.setCursor (cursor: Integer|Text) |
Sets the mouse cursor to the cursor type specified in cursor by its number or name. |
| .releaseCursor () | Restores the standard mouse cursor |
Miscellaneous
| Functions | Action |
|---|---|
.getScreenshot ({page:Integer}) : Picture |
Returns the form as a picture. See FORM SCREENSHOT |
Form definition access
| Properties | Description | Type | Writable |
|---|---|---|---|
| .formObjects | All form objects names | Collection |
x |
| .staticTexts | All static text names | Collection |
x |
| .staticPictures | All static pictures names | Collection |
x |
| .statics | All static form object names (Texts & Pictures) | Collection |
x |
| .subforms | All subform form object names | Collection |
x |
| .instantiatedWidgets | All instantiated widgets objects | Collection |
x |
| .instantiatedSubforms | All instantiated subforms objects | Collection |
x |
Class diagram
classDiagram
class form["cs.form"] {
+cs.static static
+cs.widget widget
+cs.button button
+cs.picture picture
+cs.dropDown dropDown
+cs.stepper stepper
+cs.thermometer thermometer
+cs.selector selector
+cs.comboBox comboBox
+cs.listbox listbox
+cs.hList hList
+cs.subform subform
+cs.webArea webArea
+cs.window window
+cs.constraints constraints
+init()
+handleEvents(e : cs.evt)
+onLoad()
+update()
+onBoundVariableChange()
+saveContext()
+restoreContext()
+onOutsideCall()
+focused : Text
+highlight : Text
+darkScheme : Boolean
+lightScheme : Boolean
+resourceScheme : Text
+darkSuffix : Text
+worker : Variant
+containerName : Text
+container : Object
+containerInstance : Object
+containerValue : Variant
+events : Collection
+callback : Text
+page : Integer
+formObjects : Collection
+staticTexts : Collection
+staticPictures : Collection
+statics : Collection
+subforms : Collection
+instantiatedWidgets : Collection
+instantiatedSubforms : Collection
+rect : rect
+horizontallyResizable : Boolean
+minWidth : Integer
+maxWidth : Integer
+verticallyResizable : Boolean
+minHeight : Integer
+maxHeight : Integer
+removeFocus()
+focusNext()
+focusPrevious()
+setEntryOrder()
+resourceFromScheme()
+refresh(tick : Integer)
+setTimer(tick : Integer)
+stopTimer()
+callWorker(method : Text; param 1-N)
+getContainerValue()
+setEvents(events)
+appendEvents(events)
+removeEvents(events)
+postKeyDown(key : Integer; modifier : Integer)
+callMeBack(param 1-N)
+callMe(method : Text; param 1-N)
+callChild(subform : Text; method : Text; param 1-N)
+callParent(event : Integer)
+setPageNames(names : Collection)
+goToPage(page : Variant; parent : Boolean)
+firstPage(parent : Boolean)
+lastPage(parent : Boolean)
+nextPage(parent : Boolean)
+previousPage(parent : Boolean)
+setCursor(cursor : Variant)
+releaseCursor(cursor : Variant)
+beginDrag(uri : Text; data : Variant; icon : Picture)
+getPasteboard(uri : Text) Variant
+getSubformInstance(name : Text) Object
+setHorizontalResising(resize : Boolean; min : Integer; max : Integer)
+setVerticalResising(resize : Boolean; min : Integer; max : Integer)
}