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


Mandatory

Allowed values :
remove | clear | update | add_before | add_after | enable | disable

To specify the exact change that should be applied to a form field.

Allowed values :
 

  • remove - Deletes the specified field from the form

  • clear - Resets a field's value to empty

  • update - Modifies a field's properties

  • add_before - Inserts a new field before the target field ( field specified in the name parameter )

  • add_after - Inserts a new field after the target field ( field specified in the name parameter )

  • enable - Activates a field based on input (making it interactive )

  • disable - Deactivates a field based on input (making it non-interactive)

name

String
Mandatory

Unique name of the target field where the change defined in the type attribute should be applied.

input

JSON Object
Optional

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).