Home > Tutorials > Introduction to SmartClient 8.1/SmartGWT 2.5 Validation (part 3)

Introduction to SmartClient 8.1/SmartGWT 2.5 Validation (part 3)

October 19, 2011

Up to this point of the introduction series you have seen how to apply validators to fields and create custom validators. Now we take a look validation features to control when validation occurs and how errors are shown.

Controlling validation

As has been shown previously validation can be performed on a form by calling myForm.validate() at any time. This is not the only way to trigger validation. A single form item can be validated by calling myFormItem.validate() as well. In both cases the return value is a boolean indicating if the validation was successful.

In addition to manually triggered form validation, a form is always validated before saving. The save is not performed if validation fails. The same process is repeated on the SmartClient Server Framework before a save is completed. Validation failures are reported back to the client and save is aborted.

Client-side validation can be disabled on a form by setting myForm.disableValidation to true. When set no validation is performed on calls to myForm.validate() or saveData(). Server validation is still performed on save. This setting does not affect any field-level validation triggers.

Automatic field-level validation

Form fields can be validated automatically on loss of focus (field exit) or on each value change. To enable validation on change set myFormItem.validateOnChange to true. Validation on the field will occur after the transformInput() handler has been called and before the form item’s change() handler. If validation fails the value change will not be saved into the field value nor will the change() handler be called.

Validating on a change is useful when the value in the field should always be in a valid state. This doesn’t work well for a date because it is invalid by design during partial entry. It should only be valid when leaving the field. Enter validateOnExit. By setting this property to true, the field will be validated just before calling the field’s editorExit() handler.

Normally, field focus moves to the next field even when validation fails when validateOnExit is true. To force the user to remain in the invalid field instead, set myFormItem.stopOnError to true. This implies that myFormItem.synchronousValidation is enabled so server-only validators are processed synchronously. The synchronousValidation setting is covered in a later in Advanced features.

Setting hierarchy

In many cases the FormItem settings can also be made at the DynamicForm level. For example, if all fields with validators should be validated when leaving the field, set myForm.validateOnExit to true. This validation will be performed if either myForm or myFormItem has validateOnExit true.

The validateOnChange setting is slightly different. This setting can be made at the form, field or validator level. If either the form or field validateOnChange is true validation is performed on each value change. Validations are also performed for any validator marked validateOnChange:true. However, any validator explicitly marked with validateOnChange:false is skipped during this validation step no matter what the other settings are. Some validators just don’t apply during the change phase.

Field dependencies

When working with custom validators they likely refer to more than one field on the record. Consider a custom validator that validates that one field is greater than another. If either field is changed the validator on the other field must be re-evaluated. This can be accomplished by providing the list of field dependencies for the validator as dependentFields:

Assume there is a pre-defined validator called “isGreaterThan” that compares the current field value against the current value of another field. The following DataSource will enforce that max is greater than min whenever the record is saved or validated or the max field value is changed. What happens when the min field value is changed? Nothing.

<DataSource ID="reorder">
        <field name="min" title="Min. Qty" type="integer" required="true"/>
        <field name="max" title="Max. Qty" type="integer" required="true">
                <validator type="isGreaterThan" otherField=”min” validateOnChange=”true” />

By adding dependentFields to the min field we can fix this situation:

<DataSource ID="reorder">
        <field name="min" title="Min. Qty" type="integer" required="true"/>
        <field name="max" title="Max. Qty" type="integer" required="true">
                <validator type="isGreaterThan" otherField=”min” validateOnChange=”true”>

Now, whenever the field value of min changes, the validator on max will be fired. This occurs even if validateOnChange is not true on the min field.

There is one other way to provide dependencies: declare a conditional validator. This will be covered in a later section.

Error display styles

SmartClient supports many different error display styles. These settings can even be mixed on a form per form item. By default errors are shown to the left of the field with just an error icon. Hovering the mouse over the mouse displays the full text of the error(s). To accomplish this, SC uses the following DynamicForm default settings:

showErrorIcons : true
showErrorText : false
showErrorStyle: true
showInlineErrors : true
errorOrientation : “left”

A FormItem has many of the same properties to control the display of errors as the DynamicForm. If no override value is provided at the field level, the DynamicForm settings applies. This makes is easy to define the form-wide settings and tweak one or two fields to show differently.

The icon shown can be changed with the following properties: errorIconSrc, errorIconHeight and errorIconWidth. These are normally provided by the selected skin or default from the base FormItem class.

The position of the icon can be changed by setting errorOrientation to “top”, “bottom”, “left” or “right.” This orientation is in relationship to the input field itself unrelated to the field title. If text is shown inline as well (showErrorText: true), it uses the same orientation and follows the error icon if displayed. When showing error text on the left or right, the amount of space taken from the field can be adjusted by setting errorMessageWidth on the specific field. The default is 80 pixels (80) and is limited by the column width.

Fields that are in an error condition can also be styled uniquely. By default a FormItem use CSS style “formCell” (as set in cellStyle). When showErrorStyle is false this same style is applied. Setting showErrorStyle to true causes to SmartClient to apply a CSS style of the value from cellStyle with “Error” appended (“formCellError” by default). This style in the latest skins writes the field title in bold.

If you are showing fields without titles and handling errors with just an icon it might be helpful to include the field title in the error hover message. To do so, set form.showTitlesWithErrorMessages to true. Messages will be placed in the tooltip after the title and a colon (:).

Showing errors as a group

In addition to the style of inline errors just covered, errors can be shown as a group for the form. This is common for a densly packed form where there is not room for error icons or text. To turn off inline errors set form.showInlineErrors to false.

For group error display, a special error cell (field type “blurb”) is created and shown at the top of the form when any field has errors. The field’s cellStyle defaults from form.errorItemCellStyle (“formItemError”) allowing customization of the display.

In this blurb the errors are shown formatted from form.GetErrorsHTML(). That is, each field in error is shown as a bullet item along with the error message(s). A preamble message is typically shown above this list. The text for this message is defined in form.errorsPreamble as defaults to “The following errors were found:”.

Choosing the cell style for the errors group is not the only customization that can be done. The error display is just a form item so any form item properties can be defined on this field by setting them in form.errorItemProperties. This property is an object with the desired properties.

For example, if you want to launch help when anything is clicked on this item, set properties like:

myForm.errorItemProperties : {
    click : “form.launchHelp()”

Hidden field errors

Hidden fields can be validated by a call to myForm.validate(true). Note the true argument. This tells the validation process to include hidden fields. Normally it is assumed that hidden fields are managed by code to be valid or are always valid when hidden.

When showing errors inline, there is no where to show an icon or message because the field is hidden. If errors are shown as a group, hidden errors are included. What do you do with hidden errors in inline mode? There is an event handler that allows you to do whatever you want like showing a message box.

handleHiddenValidationErrors is a string method so you can just call your display method using the errors parameter.

handleHiddenValidationErrors : “myForm.showHiddenErrorBox(errors)”;

Non-validator errors

Validators are just one way of setting errors on a field. Validation failures make the equivalent of calls to DF.addFieldErrors to store the error messages. You can do this programmatically as well. Say your form needs to perform some validation on another form or object (a valuesManager is not appropriate). After calling the normal myForm.validate() this additional validation results in errors for one or more fields. These errors can be added to the form’s error list by calling myForm.addFieldErrors. These errors then show exactly like errors that result from validators.

myForm.addFieldErrors(“email”, “Email must be entered when …”, true);

Note the last argument of true. This forces a redraw of the field so the errors show immediately. If you have a number of fields to update you can optimize this process by passing false instead and then calling myForm.showErrors() to redraw fields with errors.

WARNING: Performing form validation or validation of the field updated with your non-validator errors (like with field.validateOnChange) clears your custom message(s).

Finally, errors can be cleared on demand with a call to myForm.clearErrors (all fields) or myForm.clearFieldErrors (one specific field). MyForm.setFieldErrors is a shortcut for calling clearErrors() and then addFieldErrors().

Determine validation state

There are many cases where a form needs to determine the current validation status of its fields such as for enabling or disabling action buttons.

The SmartClient DynamicForm has some helpful methods for just this use:

  • hasErrors()
  • hasFieldErrors()
  • valuesAreValid()
  • getValidatedValues()

The first, hasErrors(), returns true if the form currently has any errors. The second, hasFieldErrors(), is the same except it only checks a single field. For both of these validation must have been performed previously to be useful.

The last two methods actually trigger validation but valuesAreValid() does not save any validation errors on the form. A call to getValidatedValues() is the same as calling getValues() except that validation is performed first and values are only returned if there are no errors.

%d bloggers like this: