Form Change Handler
The form change handler allows real-time modifications to a form's structure or behavior based on user input in a specific field.
When a field with the boolean attribute trigger_on_change: true is added, the change handler is triggered and can be used to alter the form's structure.
These modifications can include adding or removing fields, updating the properties of form fields, and enabling or disabling inputs, among other changes.
The list of attributes that are passed when this handler is triggered is given below
Attribute Name | Data Type | Description |
access | Map | Details of the web client used by the user, including the user ID and chat ID. |
environment | Map | Details about the data centre to which the user belongs |
user | Map | Details of the user who has triggered the function. |
chat | Map | Chat details in which the function is triggered. |
form | Map | Details of the form object and the input values. |
target | Map | Details of the field and the selected input that triggered the change |
Form Modification Object
The form modification object is a JSON structure that defines the changes to a form when a specific condition (such as a field's value change) is met.
It includes a list of actions where modifications such as adding, removing, or updating form elements can be applied.
Syntax
{
"type": "form_modification",
"actions": [
$action_object
]
}
Note : The actions attribute is a JSON array with a maximum size of 25 elements.
The actions object attributes:
Attribute Name | Data Type | Description |
type | String
Allowed values : | To specify the exact change that should be applied to a form field. Allowed values :
|
name | String | Unique name of the target field where the change defined in the type attribute should be applied. |
input | JSON Object | To specify the new field or value (Applicable for types - add-before, add-after, update) to be added or modified. |
Actions object syntax :
{
"type": "remove | clear | update | add_before | add_after | enable | disable",
"name" : reference_label_name
"input" : $input_element // Optional, used for add_before, add_after, update
}
Example:
Let's look at an example of how a form change handler can be configured for different types of actions on a job application form. Consider a slash command /jobapplication that triggers a form to record a candidate's job profile. When the user executes this command, a form will appear, allowing the user to select a job type and input relevant details based on their selection.
/jobapplication - Slash Command
The job application form contains fields that dynamically change based on user input. Initially, the Portfolio Link, Technical Qualification, and Visa status fields are disabled. These fields are enabled or modified depending on values selected in other fields.
Two fields in the form have trigger_on_change set to true:
Job Type (Drop-down Menu: Developer Defined) - Alters the form's structure based on the selected job type.
Requires Visa (Toggle input) - Enables the Visa Status field when selected.
return {
"type":"form",
"title":"Zylker Job Hunt",
"name":"jobApplicationForm",
"hint":"Ready to get hired? Sign up for the Zylker Annual Job Hunt today!",
"button_label":"Apply",
"inputs":{
{
"label":"Job Type",
"name":"jobType",
"trigger_on_change":true,
"placeholder":"Choose a job type from the list of options",
"multiple":false,
"mandatory":true,
"type":"select",
"options":{
{
"value":"fulltime",
"label":"Full-Time"
},
{
"value":"internship",
"label":"Internship"
}
}
},
{
"label":"Email",
"name":"email",
"placeholder":"scott.fisher@example.com",
"min_length":"0",
"max_length":"100",
"mandatory":false,
"type":"text",
"format":"email"
},
{
"label":"Portfolio Link",
"name":"portfolioLink",
"placeholder":"Add your portfolio link here!",
"min_length":"0",
"max_length":"500",
"disabled":true,
"mandatory":false,
"type":"text",
"format":"url"
},
{
"label":"Technical Qualifications",
"name":"summary",
"placeholder":"Tell us about yourself... ",
"disabled":true,
"min_length":"0",
"max_length":"1000",
"mandatory":false,
"type":"textarea"
},
{
"label":"Requires Visa",
"trigger_on_change":true,
"name":"visa",
"value":false,
"type":"toggle"
},
{
"label":"Visa Status",
"name":"visaStatus",
"placeholder":"Yet to Apply or Approved ",
"min_length":"0",
"disabled":true,
"max_length":"50",
"mandatory":false,
"type":"text"
}
},
"action":{
"type":"invoke.function",
"name":"jobApplicationFormfunction"
}
};
jobApplicationFormfunction - Form Change Handler
targetName = target.get("name");
info targetName;
inputValues = form.get("values");
info inputValues;
actions = list();
// Case 1 - When job type is selected as full time
if(targetName.containsIgnoreCase("jobType") && inputValues.get("jobType").get("value") == "fulltime")
{
actions.add({"type":"enable","name":"summary"});
actions.add({"type":"add_after","name":"jobType","input":{"label":"Years of Experience","name":"years_experience","placeholder":"Please enter your years of experience","min":"0","max":"25","mandatory":true,"type":"number"}});
actions.add({"type":"update","name":"portfolioLink","input":{"label":"Portfolio Link","name":"portfolioLink","placeholder":"Add your portfolio link here!","min_length":"0","max_length":"500","mandatory":false,"type":"text","format":"url"}});
}
// Case 2 - When job type is selected as internship
if(targetName.containsIgnoreCase("jobType") && inputValues.get("jobType").get("value") == "internship")
{
actions.add({"type":"remove","name":"years_experience"});
actions.add({"type":"update","name":"portfolioLink","input":{"label":"Portfolio","name":"portfolioLink","placeholder":"Please upload your curriculum vitae to asses your profile","mandatory":false,"type":"file"}});
actions.add({"type":"clear","name":"summary"});
actions.add({"type":"disable","name":"summary"});
}
if(targetName.containsIgnoreCase("visa") && inputValues.get("visa") == true)
{
actions.add({"type":"enable","name":"visaStatus"});
}
if(targetName.containsIgnoreCase("visa") && inputValues.get("visa") == false)
{
actions.add({"type":"clear","name":"visaStatus"});
actions.add({"type":"disable","name":"visaStatus"});
}
// Case 3 - Job Type deselected ( No selection )
if(targetName.containsIgnoreCase("jobType") && inputValues.get("jobType").isEmpty() == true)
{
actions.add({"type":"clear","name":"visaStatus"});
actions.add({"type":"disable","name":"visaStatus"});
actions.add({"type":"clear","name":"visa"});
actions.add({"type":"clear","name":"email"});
actions.add({"type":"update","name":"portfolioLink","input":{"label":"Portfolio Link","name":"portfolioLink","placeholder":"Add your portfolio link here!","min_length":"0","max_length":"500","mandatory":false,"type":"text","format":"url","disabled":true}});
actions.add({"type":"clear","name":"summary"});
actions.add({"type":"disable","name":"summary"});
actions.add({"type":"remove","name":"years_experience"});
}
return {"type":"form_modification","actions":actions};
Code Explanation
Case 1: Job Type = Full Time
When the job type is selected as Full Time:
A new field, Years of Experience*, is added after the job type dropdown (type = add_after).
The Portfolio Link and Technical Qualification fields are enabled (type = enable).
If switching from Internship to Full Time, the Portfolio field is also updated back to a link input (type = update).
Case 2: Job Type = Internship
When the job type is selected as Internship:
The Years of Experience field is removed (type = remove) as it's not relevant for interns.
The Portfolio field (initially a link input) is updated to a file upload input, allowing applicants to upload their resumes (type = update).
Any values entered when Full Time was previously selected are cleared (type = clear).
The Technical Qualification field is disabled (type = disable), as it's not required for internship applicants.
Case 3: Job Type Deselected (No Selection)
If the user deselects all options in the Job Type dropdown:
The form is reset to its initial state:
All fields are cleared of values and previous selections (type = clear).
The Portfolio field is updated back to a link input (type = update).
The Technical Qualification and Visa Status fields are disabled (type = disable).