Note: Before proceeding, get acquainted with the Settings Levels section of LyciaLowCode Settings page (the concept of levels is essential for configuring multiple interactions and the multitable support).
The definitions like LET <setting_variable>.<setting_name> = <value> refer to the InteractForm_Settings level, while LET <setting_variable>.views["<db_table_name>"].<setting_name> = <value> refers to the View level.
This setting can be defined for:
InteractForm_Settings level: Yes
View level: No
translations is an optional property, used to localize errors and messages produced by LowCode applications. This feature facilitates an easy customization and localization of strings, such as prompts, labels, and confirmation messages. This is particularly useful for customizing standard form messages like "Yes", "No", "Cancel", or confirmation prompts generated by Lycia LowCode.
This comes in a form of a map of translations, and is a HASHMAP of STRING. The key of the HASHMAP is the original string, and the value is the customized / localized string:
LET <settings_var>.translations["<original_string>"] = "<localized_string>"
Example:
LET settings.translations["Do you really want to delete this item?"] = "Möchten Sie diesen Artikel wirklich löschen?"
This setup offers several advantages:
By using these features efficiently, developers can create multilingual applications that cater to a global audience, improving usability and user satisfaction.
Example program:
DATABASE cms_llc
IMPORT FGL lib_llc_interact_form
GLOBALS "../../../lib_llc_interact_form/llc_interact_form.4gl"
MAIN
DEFINE form_settings InteractForm_Settings -- Initialize form settings
INITIALIZE form_settings.* TO NULL
LET form_settings.form_file = 'hello_alch_test'
LET form_settings.confirm_accept = 1
LET form_settings.confirm_cancel = 1 -- Define custom translations
LET form_settings.translations["Modify"] = "Змінити"
LET form_settings.translations["Do you want to save changes?"] = "Ви бажаєте зберегти зміни?"
LET form_settings.translations["Yes"] = "Так"
LET form_settings.translations["No"] = "Ні"
LET form_settings.translations["Cancel"] = "Відмінити" -- Call the form with customized settings
CALL InteractForm(form_settings)
END MAIN
Here is the list of internal LowCode messages that can be provided as original strings to the .translations setting.
# LowCode cannot define which View does the event belong to
"Event handler"
"Event '%1' can not be handled. Current view is undefined"
# ON ACTION Refresh
"Refresh"
"Do you want to save changes before refreshing data?"
"Save Data and Refresh"
"Save"
"Don't Save"
"Cancel"
# ON ACTION Save
"Modify"
"Save all changes?"
"Save"
"Cancel"
# ON ACTION Reset
"Reset"
"Reseting will remove all unsaved data. How do you want to proceed?"
"Go Back to Editing"
# AFTER INPUT
"Modify"
"Save all changes?"
"Yes"
"Cancel"
"Discard all"
# The setting id is listed in .4gl file, but there isn't a setting with such an id in the .fm2 form file
"Interact settings"
"Interact setting '%1' was not found."
# The view_table has not been defined properly in .4gl file
"Interact settings"
"The 'view_table' property is required. Check if you have defined it for all views in 4gl code."
# The view_table has not been defined properly in the .fm2 file
"Interact settings"
"The 'view_table' property is required. Check if you have defined it for all views in the form file."
# The screen_record has not been defined
"Interact settings"
"The 'screen_record' property is required. Check if all final views have defined 'screen_record' in the form file or 4gl code."
# No write permission for the log file
"Log File Access Error"
"Invalid permission (Write) for log file "
# The LowCode setting .views has not been defined or is empty
"Initialize"
"The view is undefined."
# There is a reference of the views that forms a circular dependency
"There is circular view dependencies."
# Validation of proper view_table initialization
"Initialize"
"The mandatory setting view_table is not defined."
# Validation of proper screen_record initialization
"Initialize"
"The mandatory setting screen_record is not defined."
# The screen record is missing or empty
"Initialize"
"Screen record '%1' is not defined in the form or it is empty in the form '%2'."
# The field cannot be found in the form
"Initialize"
"Field '%1' from screen record '%2' doesn't exist in the form '%3'."
# Database table or fields were not found
"Initialize"
"Table '%1' doesn't exist in database or some fields are missing in the table. (%2)"
# The ComboBox population failed
"Combobox populating"
"Populating of combobox '%1' is failed. Error code %2. %3"
# The list of values in a ComboBox depends on the field value that cannot be retrieved
"Validating"
"Validating of conditional lookup combobox '%1' is failed. Value of field '%2' can not be retrived"
# The SQL query was not able to retrieve the list of values for the ComboBox
"Validating"
"Validating of conditional lookup combobox '%1' is failed. Error code %2. %3"
# No valid value was found at the attempt of retrieving the list of values for a ComboBox
"Validating"
"%1 value '%2' is not valid for the %3"
# The lookup zoom depends on the field value that cannot be retrieved (for instance, the field was not found)
"Validating"
"Validating of conditional lookup zoom '%1' is failed. Value of field '%2' can not be retrived"
# The SQL query has failed at retrieving the list of values for the zoom
"Validating"
"Validating of conditional lookup zoom '%1' is failed. Error code %2. %3"
#The record is locked by another user or session
"Another user/session is already modifying record"
# LowCode has tried to lock the record and checks whether the field has already been changed
"Row in the table '%1' doesn't exist any more or primary key has been modified"
# LowCode has tried to lock the record and encountered that the record is already locked
"Row in the table '%1' is locked. Error code %2. %3"
# LowCode has tried to lock the record and encountered that the record has already been modified
"Another user/session has already modified record"
# At data refresh, LowCode encountered that there is unsaved data
"Do you want to save changes before refreshing data in view '%1'?"
#Inserting of new record was successful
"Insert %1 Successful operation"
#The value has been updated successfully
"Edit %1 Successful operation"
#Updating of the item has failed
"Editing item in the table '%1' failed with the error code %2. %3"
# Inserting to the database table has failed
"Adding item to the table '%1' failed with the error code %2. %3"
# Deleting from the database has failed
"Deleting from the table '%1' failed with the error code %2. %3"
# This can happen if the View is in the paged mode, and the record the program user tries to edit is not in the currently loaded page (the user has scrolled past the page containing that record)
"Selected row is out of buffer"
"Make sure that you select the correct row for the update"
# AFTER DIALOG: Updating the field in the database
"Modify"
"Do you want to save changes?"
"Yes"
"No"
"Cancel"
"Edit %1 Successful operation"
#AFTER DIALOG: Inserting
"Add"
"Add new item?"
"Yes"
"No"
"Cancel"
"Insert %1 Successful operation"
#Deleting current record
"Selected row is out of buffer"
"Make sure that you select the correct row to delete"
"Delete"
"Do you really want to delete this item?"
"Yes"
"No"
"Delete %1 Successful operation"
#Prompting for query restrictions
"Please input query criteria"
#Renewing all buffer data
"Refresh"
"Refreshing will remove all unsaved data. Do you want to proceed and refresh?"
"Cancel"
#Delete
"Delete %1 Successful operation"
#Value validation
"%1 value '%2' is not valid for the %3"
#Adding items to the table
"Add"
"Add new item?"
"Adding item to the table '%1' failed with the error code %2. %3"
# LowCode cannot update the records for the entire View if the View is in the paged mode (only one page is loaded to the buffer).
"Bundle update"
"The bundle update can not be performed because the view %1 is in buffered mode.\Use settings.paged_mode= -1\nto turn the buffering off"
# If there's an attempt to set values for the entire View, and there is an embedded array set using SetEmbeddedData() function, use the SetEmbeddedData() to update that data.
"The bundle update of the view %1 can not be performed. You should use the method SetEmbeddedData for updating embeded data."
# If there's an attempt to set values for the entire View, and the View doesn't have a Primary Key defined, it is impossible for the LowCode to define which records to update
"The bundle update with inserting and deleting records can not be performed because the view %1 doesn't have the primary key."
# At LowCode initializing, the number of fields in the view record does not match the number of fields in the record of embedded dynamic array
"Embedded data has different count of fields then fields of the view '%1'"
# Validation of data type for embedded data at LowCode initializing
"LowCode allows only DYNAMIC ARRAY OF RECORD data type embedded. See the calling function SetEmbeddedData"
# The mandatory screen record has not been defined for this View
"The 'screen_record' property is required. Each view needs to have an associated screen_record! This can be defined in the form or in the 4gl code."
# Since a View is an interaction with a specific database table, it has to contain a name of the table for reference. This error occurs when LowCode cannot find a table with such a name.
"The specified table '%1' is not in the database. Make sure you have defined the view name correctly."
Additionally, LowCode provides the public localization functions LSTRS(), LSTRT(), and LSTRC() to handle the localization of various types of strings programmatically. These methods provide extended capabilities for translating strings, table names, and column / field names. They enhance the standard Lycia LSTR() function by adding specific search mechanisms tailored for use within applications with Lycia LowCode if no translation is found in the internal engine. They integrate with the internal translation engine, user-defined mappings, and UI components to deliver a human-readable, localized experience.
The LSTRS method is designed to translate input strings, including messages and general text. It follows a specific sequence to locate the translation:
1. Search for a translated string in the map translations of the InteractForm object (or it was set in InteractForm_Settings);
2. Search for a translated string using the Lycia function LSTR().
Example:
-- Assuming InteractForm_Settings.translations["Submit"] = "Enviar"
DISPLAY iForm.LSTRS("Submit") -- Returns "Enviar" based on the InteractForm settings
The LSTRT method translates a table name into a human-readable format, following this sequence:
1. Search for a translated string in the map translations of the InteractForm object (or it was set in InteractForm_Settings). It will search in the form for the defined alias $human$<table_name> and get the tableName property of this alias. For instance, iForm.LSTRT("activity") will look for the alias below in the form and return CMS Contact Activity:
<form.database>
<Database name="cms">
<Database.dbTables>
<DbTable tableName="CMS Contact Activity" alias="$human$activity" />
</Database.dbTables>
</Database>
</form.database>
2. Search for a translated string using Lycia function LSTR().
The LSTRC method translates the input field_name to the human-readable name. It uses the following sequence:
1. Search for a translated string in the map translations of the InteractForm object (or it was set in InteractForm_Settings). It will search for the label with the identifier lb_<field_name> in the form and get the Text of this label. For instance, iForm.LSTRC("cont_name") will look for the label lb_cont_name in the form below and return Contact Name:
<Label text="Contact Name" fieldTable="" identifier="lb_cont_name"/>
<TextField fieldTable="contact" identifier="cont_name"/>
2. Search in the form for the parent TableColumn of the input field and get the Text of this table column. For example, iForm.LSTRC("cont_name") will look for the TableColumn in the form below and return Contact Name:
<TableColumn text="Contact Name" identifier="clm_cont_name" >
<TextField fieldTable="contact" identifier="cont_name"/>
</TableColumn>
3. Search for a translated string using Lycia function LSTR().
Once a translation is found using any of the aforementioned methods, it is stored in the translations property of the InteractForm object. Subsequent calls to LSTRS(), LSTRT(), or LSTRC() for the same identifier will directly use the cached translation.
These methods provide an extended layer of localization for applications with Lycia LowCode, ensuring flexibility and precision in translating UI elements and messages. They build upon Lycia's LSTR() function while adding custom search paths to accommodate LowCode-specific configurations and data structures.