Part one of two, in a series.
The simple premise is that I’d like to be able to write a client-side form validation once in (Lotus) Domino Designer and run it anywhere. Sounds like a recipe for JavaScript, right? Ah, but there’s a catch. A few catches to be precise. First off, AFAIK JavaScript version support in the Notes client has been frozen at about 1.3 since R5. What that means for practical purposes is that I was unable to use the Object.hasOwnProperty
method in my validation object (more on that later.) Also, the Notes client doesn’t support DHTML-style rendering in JavaScript to place field validation messages directly on the form as is common practice in webforms.
To begin with, I created a simple JavaScript validation object that will hold all validation logic. The object has arrays for individual field validation rules, an array for messages to display if the validation fails for any of the fields, a boolean pass or fail property, a property that contains the field to focus on in a failure event (the first field to fail validation) and some other housekeeping properties:
function ValidationObject(aform){ this.form = aform; this.isValid; this.focusOn = null; this.validationMessages; this.errorMessage this.fieldValidations this.setValidations = oSetValidations; this.validate = oValidate; }//ValidationObject
ValidationObject
has two methods, setValidations
, which populates the individual validation rules for a form (the aforementioned array) and validate
, which performs the validation, returning true or false for pass/fail. The real interesting logic is in setValidations
:
//rule array is 2 dimensional array. //inner array is 3 or 4 elements, 4th is optional //element 1: field name (HTML name) //element 2: field type (String) {TEXT|EMAIL|DATE|CHECK|RADIO} //element 3: failure message //element 4: optional arguments key:value object (ex: {emptyOk: true}) function oSetValidations(vRuleArr){ if (vRuleArr.constructor != Array) { this.errorMessages = "validation rules error: not an array"; return false; } for (i = 0;i<vRuleArr.length;i++){ var ruleArr = vRuleArr[i]; if ((ruleArr.constructor != Array) || (ruleArr.length < 3) || (ruleArr.length > 4)){ this.errorMessage = "validation rules error: rule " + i + 1; return false; } } this.fieldValidations = vRuleArr; return true; }//oSetValidations
Each field on the form to be validated is defined by a rule array that is an element in the vRuleArr
array parameter. Standard stuff, the parameters are defined in the comments above the code snippet above, no need to repeat myself. The ast parameter, an optional Object literal containing key:value pairs that the validation logic can use to branch on, needed to be backported to the JS that Notes supports due to the aforementioned Object.hasOwnProperty
issue. To solve, I was able to use Object.propertyname == undefined
to perform the same logic in a Notes client-friendly manner. A snippet of the validate method highlights:
function oValidate(){ this.isValid = true; this.validationMessages = new Array(); for (i = 0;i<this.fieldValidations.length;i++){ var rule = this.fieldValidations[i]; var hasOpts = (rule.length == 4) ? rule[3] : false; var fld = eval("this.form." + rule[0]); if (rule[1] == "TEXT"){ emptyOk = (hasOpts && (hasOpts.emptyOk != undefined) && hasOpts.emptyOk) ? true : false; if ((fld.value.split(' ').join('') == "") && (!emptyOk)) { if (this.isValid) this.focusOn = fld; this.isValid = false; this.validationMessages.push(rule[2]); } } else if (true) { //MORE VALIDATION TYPES…………. } } if (!this.isValid){ alert(this.validationMessages.join('n')); this.focusOn.focus(); } return this.isValid }//oValidate
Line 9 is where I needed to query the optional arguments object for the text validation logic. All this is leading up to a larger issue of how to perform a simple submit in the Notes client, contingent on validation and close the document using as much common code as possible for Notes and the web. Stop me if you’ve heard this before. To be continued. Please chime in with your feedback.