Dependent field modifies a field on a form depending on the value of one or more other fields.
Note that only value and dropdown modes are currently implemented.
Dependent field has three modes:
- value – set the value of the field
- dropdown – set the items in the dropdown
- show – show or hide the field
The modification is controlled by server-side processing, which can either be run or executed.
Value mode
In value mode the dependent field is only set if it was initially blank and if the user has not modified it. Once the user has modified the field, it is not changed.
Dropdown mode
Dropdown mode runs initially and every time any of the depends on field changes.
Show mode
show mode runs initially and every time any of the depends on field changes.
Options
Each of these is specified in the same way, using a class of "dependent-field" and a data-options attribute. The data options may contain the following.
mode | The mode. Must be one of "value", "dropdown" or "show". |
dependsOn | The name of the field on which this depends, or an array of field names. |
method | Whether to "execute" or "run" a script. |
script | When method is run, the node version reference of the script to run. |
context |
When method is run, value to be passed as the context parameter. When method is execute, node to be executed. Defaults to the nodeVersionReference of the page. |
params |
Additional parameters to be passed to the script or the execute. For execute, this would typically include an action parameter. |
lookup |
As an alternative to setting a script, provide a lookup object which provides values for the data for the first or only depends on field. For example, { This is most useful for dropdowns, where each value in the lookup object would be an items array. Use a "default" lookup property for unknown values. If you want to share lookups between fields, you can write the lookup to a hidden field or a hidden div, and provide jQuery selector for it in lookup. For example { Means "read lookup value from the value of the lookup-values input. Alternatively, you could use a div, something like. <div class="d-none" id="lookup-values"> And then use this { |
Script conventions
The executed or run script will be passed the following parameters.
context | In run mode, the calling context. In execute mode, this can be found using application.getContext(). |
data |
A JSON object which contains the values of each of the fields on which this field depends, plus the original dependsOn as an array (a single field is converted to a 1-item array). For example, if "dependsOn" was set to ["name","email"], then data might be { |
... | Additional parameters, as specified in the params option. |
The script should return in the <return> element a JSON object the data property of which contains the required value, depending on the mode.
value | A text string for the suggested value. |
dropdown | A JSON array with objects with name and value, as used by the dropdown field "items" property. |
show | true to show the field, false to not show the field. |
Example field
This example shows how to use script mode to set the suggested value of a user id field based on an email address.
The options for this might be:
{
"mode": "value",
"dependsOn": "email",
"method": "run",
"script": "library.user.EmailToUserIdDependentFieldScript"
}
The form has two fields
<input name="email" type="text"/>
<input name="userId" type="text" class="dependent-field" data-options=".. options .."/>
Example script
The server-based script in library.user.EmailToUserIdDependentFieldScript would be something like this.
It suggest a user id based on the first bit of the email address, incrementing this as necessary if the id is already used.
var request = application.get('request');
var data = application.parseJSON(request.getString('data'),{});
function main(){
var userId = '';
// We only expect one field value, so extract it from the data
var fieldName = data.dependsOn[0];
if ( fieldName ) {
var emailAddress = data[fieldName];
var atPos = emailAddress.indexOf('@');
var nameRoot = atPos == -1 ? emailAddress : emailAddress.substr(0,atPos);
if ( nameRoot ) {
var userId = nameRoot
var nextSuffix = 2;
while(application.service(
'<UserExists><reference>' + application.escape(userId) + '</reference></UserExists>'
).getString('referenceExists') == 'true' ) {
userId = nameRoot + nextSuffix++;
}
}
}
application.put('return',application.stringify({data:userId}));
}
if (!application.errorFound()) {
main();
}
Lookups
For simple dropdown dependencies, you can use an additional parameter that contains the lookup values from the values of the depends-on field to the items that should be shown in the dependent field. If you have many dropdowns with the same dependencies, you can create a hidden lookup field that contains a lookup field.
Pass the depends-on field and the lookup as the dependsOn property.
Use a simple script to return the correct items from the lookup.
var params = JSON.parse(application.get('request').getString('data'));
var field = params[String(params.dependsOn[0])];
// Use this if passed in params
var lookup = params.lookup;
// Use this if a dependends-on hidden field
var lookup = application.parseJSON(params[String(params.dependsOn[1])],{});
var items = lookup[field];
if ( !items ) {
items = [
{ value: '', name: 'Select an option' }
];
}
application.put('return', application.stringify({data:items}));