Finally I found a name for it. Chris Blatnick named it on his blog Interface Matters.
The technique was presented to me by Patrick Kwinten a while back. He as also blogged about it here.
Since then I find the technique really appealing since it in my opinion makes the coding in domino a lot cleaner. You can create a javascript library and put all the event management in there instead of having it in forms and subforms. Personally it goes along very well with my belief in separating style and content.
Here’s an example how to dynamically change the behavior on mandatory fields. In this case it uses css to show a red border around the field which is mandatory and is missing a value. I have not included the css here. But it is basic knowledge so it should not be hard to create one your self.
This example requires prototype.js
First a function is used to get a Hash of mandatory fields. In this case the mandatory fields are different depending of a previous selection in a field. The selections are “IBAN”, “US-ABA”, “SE-BG”…
There is a function for this so that the source of the information easily can be changed. Later its easy to implement a configuration document and fetch the information via ajax.
function getMandatoryFields(){
var mandatoryFields = {
"":{"mandatory":["Tx_BankName","Tx_BankID","Tx_AccountNumber
"IBAN":{"mandatory":["Tx_BankName","Tx_BankID","Tx_AccountNumber"]},
"US-ABA":{"mandatory":["Tx_BankName",
"Tx_BankID", "Tx_AccountNumber"]},
"SE-BG":{"mandatory":["Tx_AccountNumber"]},
"SE-PG":{"mandatory":["Tx_AccountNumber"]},
"SE-Clearing":{"mandatory":["Tx_BankName",
"Tx_BankID","Tx_AccountNumber"]},
"DE-BLZ":{"mandatory":["Tx_BankName", "Tx_BankID","Tx_AccountNumber"]},
"CANADA":{"mandatory":["Tx_BankName",
"Tx_BankID", "Tx_AccountNumber"]}};
return mandatoryFields;
}
Here’s the code:
Function refreshMandatoryBankInfo(accountType, mandatoryFields){
//Get the list of fields to the specific account type
mandatoryList = mandatoryFields[accountType].mandatory;
//This is not very modular for now.
var allFields = ["Tx_Recipient","Tx_BankName","Tx_BankID","Tx_AccountNumber"];
//Now we reset all fields. Removing onFocus and onBlur events and styles for mandatory fields
for (var i = 0; i < allFields.length; i++){
$(allFields[i]).setAttribute('onFocus','');
$(allFields[i]).setAttribute('onBlur','');
$(allFields[i]).removeClassName('mandatoryField');
$(allFields[i]).removeClassName('required');
};
//Go through all mandatory fields and assign an onFocus and onBlur event.
for (var i = 0; i < mandatoryList.length; i++){
Event.observe($(mandatoryList[i]), 'focus', mandatoryOnFocusEvent);
Event.observe($(mandatoryList[i]), 'blur', mandatoryOnBlurEvent);
//Set initial class for the field.
if (IsEmpty($(mandatoryList[i]))){
$(mandatoryList[i]).addClassName('mandatoryField');
$(mandatoryList[i]).addClassName('required');
}else{
$(mandatoryList[i]).removeClassName('mandatoryField');
$(mandatoryList[i]).removeClassName('required');
}
}
}
//Function to check if field is empty
function IsEmpty(aTextField) {
if ((aTextField.value.length==0) || (aTextField.value==null)){
return true;
}else {
return false;
}
}
//The onFocus function
function mandatoryOnFocusEvent(e){
//Find source element (field which event was triggered) read more about the technique here. The difference is due to different handling in ie and mozilla.
if (typeof e == undefined) {
var e = window.event;
}
var source;
if (typeof e.target != undefined) {
source = e.target;
} else if (typeof e.srcElement != undefined) {
source = e.srcElement;
} else {
//Since it is a target type we do not handle, exit function
return true;
}
//Set class for active field (You can define a special style to show in which field the cursor is placed).
source.addClassName('activeField');
}
function mandatoryOnBlurEvent(e){
if (typeof e == undefined) {
var e = window.event;
}
var source;
if (typeof e.target != undefined) {
source = e.target;
} else if (typeof e.srcElement != undefined) {
source = e.srcElement;
} else {
return true;
}
//Remove class for active field
source.removeClassName('activeField');
//Different handle for text and textarea and a select object
if (source.type =="text" || source.type =="textarea"){
if (IsEmpty(source)){
source.addClassName('mandatoryField')
} else{
source.removeClassName('mandatoryField')
}
source.value = Trim(source.value);
//Check if select statement is empty. Select-one is for on selection if you have a multiple selection object test for select-multiple. The test if it is empty may then have to be rewritten to work.
}else if (source.type =="select-one"){
if(source.options[source.selectedIndex].text == ""){
source.addClassName('mandatoryField')
}else{
source.removeClassName('mandatoryField')
}
}
}
How the function is called:
refreshMandatoryBankInfo($F("Tx_AccountType"), getMandatoryFields());