Scripting Forms
Overview
In Servoy, each form has an associated JavaScript (JS) file, which governs its behavior at runtime. This file defines custom methods, handles events, and interacts with the form's base API, giving developers full control over UI elements and data manipulation.
Form at Design Time
At design time, a form represents a visual layout defined in the Servoy IDE. Developers configure UI components, data bindings, and form properties. This design-time form is connected to the JS file, where functionality is scripted to respond to user actions, control form behavior, and handle data transactions. By separating design and logic, Servoy ensures maintainability and clear structure in applications.
Form as a Runtime Object
At runtime, the form becomes an object with a base API, which allows developers to control components, manage data, and trigger custom logic. This API can be extended using the form’s JS file, allowing developers to implement custom behaviors, manage user interactions, and define dynamic data logic.
Encapsulation in Form JS
The form’s JS file supports encapsulation, offering:
Public methods/variables: Accessible across the entire solution, allowing interactions with other forms or modules.
Private methods/variables: Restricted to the form itself, ensuring internal logic is hidden and modular.
Protected methods/variables: Available within the form and any inherited forms, ensuring reusable and secure methods in inherited structures.
Form Methods
In Servoy, a form method is a custom JavaScript function defined within a form's script that encapsulates specific functionality or business logic. Unlike form events, which are automatically triggered by user actions or form lifecycle changes (e.g., onLoad, onShow), form methods are explicitly called by the developer to perform particular tasks. They promote code reusability, organization, and maintainability by allowing you to encapsulate frequently used logic within dedicated functions. These methods can handle tasks such as data manipulation, validation, UI updates, integrations, and more. They are defined within the form's script and can be invoked from event handlers, other methods, or even from different forms if designed as global methods.
When and How to Use Form Methods
When to Use:
Reusability: When you have logic that needs to be executed from multiple places within the form.
Organization: To keep event handlers clean by delegating complex logic to separate methods.
Maintenance: Easier to update and manage specific functionalities without affecting unrelated code.
Encapsulation: To encapsulate business logic, making the codebase more modular and understandable.
How to Use:
Define the Method: Within the form's script, define a function with a clear and descriptive name.
Call the Method: Invoke the method from event handlers, other methods, or even from different forms if necessary.
Pass Parameters: If needed, pass parameters to the method to make it more flexible and adaptable to different scenarios.
Return Values: Methods can return values to be used by the caller, enabling further processing or decision-making.
Common Use Cases with Examples
Data Manipulation (CRUD Operations)
Use Case: Handling Create, Read, Update, and Delete operations on records within a form.
Example: Saving a Record with Validation
Explanation:
saveRecord
Method: This method first calls validateForm to ensure data integrity. If validation passes, it attempts to save the data using databaseManager.saveData(foundset). It then provides user feedback based on the success of the operation.validateForm
Method: Checks that required fields are filled and that the email address is in a valid format.validateEmail
Method: Uses a regular expression to verify the email format.
When to Use: When implementing a save functionality that requires data validation before persisting to the database.
Data Retrieval and Filtering
Use Case: Searching for records based on user input or applying specific filters to display subsets of data.
Example: Searching for Customers by Name
Explanation:
searchCustomers
Method: Initiates a find mode on the foundset, sets the search criteria using wildcards for partial matching, and performs the search. It then informs the user about the number of records found.
When to Use: When implementing search functionality to allow users to find records based on specific criteria.
Form Initialization and Reset
Use Case: Preparing the form with default values when it's loaded or resetting the form to its initial state.
Example: Initializing a New Customer Form
Explanation:
initializeNewCustomer
Method: Checks if the current record is new. If so, it sets default values for date_created and status, and ensures that certain UI elements are enabled.
When to Use: When setting up the form for creating new records, ensuring that default values are populated, and UI elements are appropriately configured.
Data Validation
Use Case: Ensuring that the data entered by the user meets specific criteria before performing operations like saving.
Example: Validating Order Quantity
Explanation:
onDataChangeQuantity
Method: Attached to the onDataChange event of the quantity field. It ensures that the entered quantity is at least 1. If not, it shows a warning and rejects the change.
When to Use: When implementing field-specific validations to maintain data integrity.
Business Logic Execution
Use Case: Performing complex calculations, processing workflows, or handling specific business rules within the application.
Example: Calculating Total Order Amount
Explanation:
calculateTotalAmount
Method: Iterates through related order line items, calculates the total by multiplying quantity and unit price for each line, and updates the total_amount field.
When to Use: When implementing calculations or processing that depend on multiple data points or related records.
Best Practices for Using Form Methods
Descriptive Naming: Name methods clearly to indicate their purpose (e.g., validateForm, saveRecord).
Single Responsibility: Each method should perform a single, well-defined task to enhance readability and maintainability.
Parameterization: Use parameters to make methods flexible and adaptable to different scenarios.
Error Handling: Incorporate robust error handling within methods to manage unexpected situations gracefully.
Reusability: Design methods to be reusable across different parts of the form or even across different forms if applicable.
Documentation: Comment your methods to explain their purpose, parameters, and return values for better understanding and future reference.
Modularity: Keep methods modular to allow easy testing, debugging, and updating without affecting unrelated functionalities.
Form Variables
A form variable in Servoy is a local variable that belongs to a specific form and can be used to store and manage data at the form level. Form variables are typically used to manage temporary data, control form behavior, and interact with form elements, but they are not tied to any database column. They provide a convenient way to hold values specific to a form without affecting the underlying data model.
Characteristics of a Form Variable
Scope: A form variable is limited to the form where it is defined.
Lifecycle: It exists as long as the form is loaded and is reset when the form is reloaded or closed.
Type: Form variables can have various data types (String, Number, Date, etc.), depending on how they are defined.
When to Use a Form Variable
Form variables are useful in scenarios where you need to:
Store temporary data that does not need to be persisted in the database.
Control the state or behavior of the form (e.g., toggle UI elements or track form status).
Hold user input or selections before saving them to the database.
Implement complex logic or calculations without cluttering the database structure.
Common Use Cases with Examples
Form Variable as a Dataprovider
Form variables can be used as dataproviders in Servoy. A dataprovider in Servoy is essentially a data source for UI elements like text fields, checkboxes, and combo boxes, allowing them to display and interact with data. Typically, dataproviders are database fields, but form variables can also be assigned as dataproviders when you want to display or bind non-persistent data in the UI.
To use a form variable as a dataprovider for a UI element, follow these steps:
Create a Form Variable and define its name, data type (String, Number, Boolean, etc.), and optional initial value.
Assign the Variable as a Dataprovider:
Select the form element (e.g., a text field or label) that you want to bind to the form variable.
In the Properties section, under Dataprovider, choose the form variable as the dataprovider for that element.
Update the Form Variable Programmatically:
You can read or modify the form variable in your form methods, and the UI element will automatically update based on the variable's value.
Example: Displaying Non-Persistent Data Form variables as dataproviders are useful when you want to display information that doesn't come from the database and doesn't need to be saved.
Use Case: You have a calculated or temporary value, like a subtotal, that you want to display on the form without saving it to the database.
How to Use:
Create a form variable called
subtotal
of typeNumber
.Set
subtotal
as the dataprovider for a label or text field on the form.When the
calculateSubtotal()
method is called and the subtotal variable is updated, the UI element will reflect the new value.
Storing Temporary UI State
Form variables are often used to control the state of UI elements, such as enabling/disabling fields or showing/hiding certain sections of a form.
Use Case: A form variable is used to control whether a form field is editable or not, based on the current user’s role or the status of the record.
Example:
How to Use:
Create a form variable called
isEditMode
of typeBoolean
.Use this variable in the
toggleEditMode()
method to control whether form elements likemyTextField
are enabled or disabled.The form switches between
view
andedit
modes when a user clicks a button.
Holding User Input Before Saving
Form variables are useful for holding user input, such as search terms or selections, before the data is processed or saved to the database.
Use Case: A form variable holds a user’s search term before running a search query.
Example:
How to Use:
Create a form variable called
searchTerm
of typeString
.Use this variable to store the user’s input from a search field.
When the user clicks a
Search
button, theperformSearch()
method is triggered, using the value ofsearchTerm
to filter records.
Toggling UI Visibility
Form variables can be used to show or hide certain elements on a form based on user interactions or conditions.
Use Case: A form variable is used to toggle the visibility of a "details" panel when a user clicks a button.
Example:
How to Use:
Create a form variable called
showDetails
of typeBoolean
.Use this variable to determine whether a panel or section of the form (e.g.,
detailsPanel
) is visible or hidden.Attach the
toggleDetails()
method to a button to toggle the visibility of the panel.
Tracking Status or Workflow
Form variables can be used to track the status of a process or workflow, such as a multi-step form where the user progresses through various stages.
Use Case: A form variable is used to track the current step in a multi-step wizard.
Example: