This type of map permits you to define dependencies between fields in edit mode. For example, it will permit you to make a field read-only (not editable) or not depending on the value selected in a given field or to change the available values in a picklist depending on the value.
The goal of this mapping is to define a set of rules/conditions and actions to be applied while editing a field in a coreBOS form.
The trigger event will be the onChange HTML event. Whenever a field changes its’ value in a form we will evaluate a given set of conditions and if they are true we will apply a set of actions.
Since we will be evaluating the field on a per-module basis and to avoid additional time looking for related values via AJAX, the conditions will be evaluated using only information located on the form.
The supported condition operators are the same ones we support in the custom view filter system (see Conditional Popup and Popup Open Hook:
Group conditions can be created concatenating with the typical AND/OR operators. We will be using a similar concept to the one used for filters:
"groupid":"number that identifies the group of conditions",
"columnname":"coreBOS column identifier or simply the column/field name"
"comparator":"comparison operator"
"value":"text to look"
"columncondition":"and|or" (logical operator to join with the next condition)
The actions supported are:
"Function" leaves the door open to all sorts of options, giving total control to the programmer. We will provide a set of common functions to be used:
fieldDep_AssignNewValue: return new value in the action_field
fieldDep_CopyFieldValue: copies the value in the field defined by the first parameter into the action field
<function>
<field>description</field>
<name>fieldDep_CopyFieldValue</name>
<parameters>
<parameter>template_language</parameter>
</parameters>
</function>
fieldDep_AddDays: add the given number of days to new_value and return the result
fieldDep_SubDays: subtract the given number of days from new_value and return the result
fieldDep_OnlyNumbers: return all numbers in new_value
fieldDep_OnlyLetters: return all letters in new_value
fieldDep_GetField: will use getFieldValuesFromRecord to retrieve the value of the given field from a related record. In other words, this works on related capture fields in the record and retrieves information from the selected related record
fieldDep_AssignUser: set the assigned user to the given (user) ID parameter
fieldDep_AssignGroup: set the assigned user to the given (group) ID parameter
fieldDep_AssignUserSelect: set the assigned user to the given user ID parameter for uitype 101 fields
fieldDep_GetFieldSearch: searches for a field as reference in order to map other fields
NOT IMPLEMENTED YET
fieldDep_ChangeLabel: will permit changing the label of a field
fieldDep_Format: return sprintf formatting of new_value (use sprintf javascript library: https://github.com/alexei/sprintf.js)
The accepted format is:
<map>
<originmodule>
<originname>SalesOrder</originname>
</originmodule>
<dependencies>
<dependency>
<field>campaignname</field>
<condition>[{...}]</condition>
<actions>
<change>
<field>sponsor</field>
<value>Sponzori</value>
</change>
<change>
<field>campaignname</field>
<value>2323232</value>
</change>
<hide>
<field>targetaudience</field>
</hide>
<readonly>
<field>campaignname</field>
</readonly>
<setclass>
<field>somefield</field>
<fieldclass>someCSSclass</fieldclass>
<labelclass>someOtherCSSclass</labelclass>
</setclass>
<collapse>
<block>sponsor</block>
</collapse>
</actions>
</dependency>
<dependency>
…
</dependency>
</dependencies>
</map>
Notes
<map>
<originmodule>
<originname>CobroPago</originname>
</originmodule>
<dependencies>
<dependency>
<field>amount</field>
<condition>[{"groupid":"",
"columnname":"vtiger_cobropago:amount:amount:CobroPago_Amount:N",
"comparator":"m",
"value":"0",
"columncondition":""}]
</condition>
<actions>
<change>
<field>paymentcategory</field>
<value>Infrastructure</value>
</change>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>CobroPago</originname> </originmodule>
<dependencies>
<dependency>
<field>amount</field>
<condition>[{"groupid":"",
"columnname":"vtiger_cobropago:amount:amount:CobroPago_Amount:N",
"comparator":"m",
"value":"0",
"columncondition":""}]
</condition>
<actions>
<change>
<field>paymentcategory</field>
<value>Infrastructure</value>
</change>
<readonly>
<field>paymentcategory</field>
</readonly>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>CobroPago</originname> </originmodule>
<dependencies>
<dependency>
<field>amount</field>
<condition>[{"groupid":"",
"columnname":"vtiger_cobropago:amount:amount:CobroPago_Amount:N",
"comparator":"m",
"value":"0",
"columncondition":""}]
</condition>
<actions>
<setoptions>
<field>paymentcategory</field>
<option>Infrastructure</option>
</setoptions>
<deloptions>
<field>paymentcategory</field>
<option>Taxes</option>
<option>Travel</option>
<option>Stock</option>
<option>Sale</option>
</deloptions>
<change>
<field>paymentcategory</field>
<value>Infrastructure</value>
</change>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>Accounts</originname> </originmodule>
<dependencies>
<dependency>
<field>employees</field>
<condition>[{"groupid":"1",
"columnname":"vtiger_accounts:employees:employess:Accounts_Employees:N",
"comparator":"l",
"value":"100",
"columncondition":"and"},
{"groupid":"1",
"columnname":"vtiger_accountbillads:bill_country:bill_country:Accounts_Bill_County:V",
"comparator":"e",
"value":"Spain",
"columncondition":"or"},
{"groupid":"2",
"columnname":"vtiger_accounts:employees:employess:Accounts_Employees:N",
"comparator":"g",
"value":"100",
"columncondition":"and"},
{"groupid":"2",
"columnname":"vtiger_accountbillads:bill_country:bill_country:Accounts_Bill_County:V",
"comparator":"e",
"value":"Albania",
"columncondition":""}]
</condition>
<actions>
<hide>
<field>ownership</field>
</hide>
<collapse>
<block>LBL_ADDRESS_INFORMATION</block>
</collapse>
</actions>
</dependency>
<dependency>
<field>bill_country</field>
<condition>[{"groupid":"1",
"columnname":"vtiger_accounts:employees:employess:Accounts_Employees:N",
"comparator":"l",
"value":"100",
"columncondition":"and"},
{"groupid":"1",
"columnname":"vtiger_accountbillads:bill_country:bill_country:Accounts_Bill_County:V",
"comparator":"e",
"value":"Spain",
"columncondition":"or"},
{"groupid":"2",
"columnname":"vtiger_accounts:employees:employess:Accounts_Employees:N",
"comparator":"g",
"value":"100",
"columncondition":"and"},
{"groupid":"2",
"columnname":"vtiger_accountbillads:bill_country:bill_country:Accounts_Bill_County:V",
"comparator":"e",
"value":"Albania",
"columncondition":""}]
</condition>
<actions>
<hide>
<field>ownership</field>
</hide>
<collapse>
<block>LBL_ADDRESS_INFORMATION</block>
</collapse>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>Invoice</originname> </originmodule>
<dependencies>
<dependency>
<field>invoicedate</field>
<actions>
<function>
<field>duedate</field>
<name>fieldDep_AddDays</name>
<parameters>
<parameter>30</parameter>
</parameters>
</function>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>Contacts</originname> </originmodule>
<dependencies>
<dependency>
<field>phone</field>
<actions>
<function>
<field>phone</field>
<name>fieldDep_OnlyNumbers</name>
</function>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule>
<originname>Potentials</originname>
</originmodule>
<dependencies>
<dependency>
<field>related_to</field>
<actions>
<function>
<field>title</field>
<name>fieldDep_GetField</name>
<parameters>
<parameter>Accounts.industry,Accounts.email1</parameter>
<parameter>potentialname,nextstep</parameter>
</parameters>
</function>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>Accounts</originname> </originmodule>
<dependencies>
<dependency>
<field>bill_country</field>
<condition>
[
{"groupid":"1",
"columnname":"bill_country",
"comparator":"s",
"value":"A",
"columncondition":""}
]
</condition>
<actions>
<change>
<field>paymentcategory</field>
<value>Infrastructure</value>
</change>
<readonly>
<field>paymentcategory</field>
</readonly>
</actions>
</dependency>
<dependency>
<field>bill_country</field>
<condition>
[
{"groupid":"1",
"columnname":"bill_country",
"comparator":"ns",
"value":"A",
"columncondition":""}
]
</condition>
<actions>
<editable>
<field>paymentcategory</field>
</editable>
</actions>
</dependency>
</dependencies>
</map>
Another Example:
<map>
<originmodule>
<originname>Accounts</originname>
</originmodule>
<dependencies>
<dependency>
<field>accountname</field>
<condition>
[
{"groupid":"1",
"columnname":"vtiger_contacts:lastname:lastname:Contacts_Contact_Lastname:V",
"comparator":"c",
"value":"sel",
"columncondition":"AND"},
{"groupid":"1",
"columnname":"vtiger_contacts:email:email:Contacts_Contact_Email:V",
"comparator":"c",
"value":"gmail",
"columncondition":"OR"},
{"groupid":"2",
"columnname":"vtiger_contacts:firstname:firstname:Contacts_Contact_Firstname:V",
"comparator":"e",
"value":"albana",
"columncondition":""}
]
</condition>
<actions>
<change>
<field>phone</field>
<value>12345</value>
</change>
<change>
<field>email1</field>
<value>a@gmail.com</value>
</change>
<hide>
<field>otherphone</field>
</hide>
<hide>
<field>assigned_user_id</field>
</hide>
<readonly>
<field>fax</field>
</readonly>
<readonly>
<field>notify_owner</field>
</readonly>
<deloptions>
<field>rating</field>
<option>Acquired</option>
<option>Active</option>
<option>Shutdown</option>
</deloptions>
<collapse>
<block>CustomerPortalInformation</block>
</collapse>
</actions>
</dependency>
<dependency>
<field>accountname</field>
<condition>
[
{"groupid":"1",
"columnname":"vtiger_account:accountname:accountname:Accounts_Account_Name:V",
"comparator":"c",
"value":"corebos",
"columncondition":""}
]
</condition>
<actions>
<change>
<field>phone</field>
<value>54321</value>
</change>
<show>
<block>assigned_user_id</block>
</show>
<setoptions>
<field>rating</field>
<option>Market Failed</option>
</setoptions>
<disappear>
<block>AddressInformation</block>
</disappear>
</actions>
</dependency>
</dependencies>
</map>
<map>
<originmodule> <originname>Invoice</originname> </originmodule>
<dependencies>
<dependency>
<field>cf_879</field>
<actions>
<function>
<field>cf_879</field>
<name>changeTaxDetails</name>
<parameters>
</parameters>
</function>
</actions>
</dependency>
</dependencies>
</map>
function changeTaxDetails(change_field, action_field, new_value, old_value) {
if (action_field == 'cf_879') {
if (new_value != 'Guardias') {
document.getElementsByName('tax2_group_percentage')[0].value = 0.00;
} else {
document.getElementsByName('tax2_group_percentage')[0].value = -6.00;
}
calcTotal();
}
}
you can load the JS from a file in the footer with:
BusinessActions::addLink(getTabid("Invoice"), 'FOOTERSCRIPT', 'corebosjshookinvoice', 'modules/Invoice/corebosjshookinvoice.js', '', 0, null, false);
The application is constructed to not permit this so we have to use a trick to consciously force this.
<map>
<originmodule>
<originname>CobroPago</originname>
</originmodule>
<dependencies>
<dependency>
<field>cyp_no</field>
<actions>
<function>
<field>cyp_no</field>
<name>doNothing</name>
<parameters>
<parameter>this is a stub to force the next two functions to work. this is a conscious execution of functions on load</parameter>
</parameters>
</function>
<function>
<field>assigned_user_id</field>
<name>fieldDep_AssignUser</name>
<parameters>
<parameter>12</parameter>
</parameters>
</function>
<function>
<field>reports_to_id</field>
<name>fieldDep_AssignUserSelect</name>
<parameters>
<parameter>5</parameter>
</parameters>
</function>
</actions>
</dependency>
</dependencies>
</map>
Another example using the new functionality fieldDep_GetFieldSearch. Here we want to map some fields in AssetDetails which values will be copied from Assets using a reference field to make the search:
<map>
<originmodule>
<originname>AssetDetails</originname> {the target module}
</originmodule>
<dependencies>
<dependency>
<field>related_assets</field> {reference field, so filling this field we will trigger the search for the other ones}
<actions>
<function>
<name>fieldDep_GetFieldSearch</name>
<parameters>
<parameter>Assets</parameter> {the module where we take the desired fields}
<parameter>related_assets_sc,account</parameter> {fields we want to take the value from, in this case Assets}
<parameter>id</parameter>
<parameter>new value</parameter> {default parameter; to set new values to the fields}
<parameter>e</parameter> {operator; in this case means: equal}
<parameter>related_ad_servicecontact,account_name</parameter> {fields where we will copy the values,in this case AssetDetils; the fields must be separated by coma in respective order with the above fields from Assets}
</parameters>
</function>
</actions>
</dependency>
<dependency>
<field>related_productcomponent</field>
<actions>
<function>
<name>fieldDep_GetFieldSearch</name>
<parameters>
<parameter>ProductComponent</parameter>
<parameter>maintenance_buyingprice,maintenance_sellingprice</parameter>
<parameter>id</parameter>
<parameter>new value</parameter>
<parameter>e</parameter>
<parameter>vendor_maintenance_purchasevalue,customer_maintenance_salesvalue</parameter>
</parameters>
</function>
</actions>
</dependency>
</dependencies>
</map>
<br>
You can add as many dependencies to copy-paste field values from different modules. As you see above we have used two <dependency>
tags in order to take values from Assets when we fill the related_assets
and to take from ProductComponent filling the related_productcomponent
between <field>
tags.
Next | Chapter 14: Validations.