Home > Tutorials > Introduction to SmartClient 8.0/SmartGWT 2.2 Validation

Introduction to SmartClient 8.0/SmartGWT 2.2 Validation

August 10, 2010

SmartClient supports a very powerful validation process for form and grid editing. One or more validators can be assigned to each field providing a means to inform the user of data entry issues.

Validators are typically assigned to fields in a DataSource but can also be applied to DynamicFormFields. A major benefit of assigning validators to DataSource fields is that the validation occurs on both the client and server when using the SmartClient Server Framework. If you are not using the SC Server Framework you will have to write validation logic on the client and server.

Taking server validation one step further, the SC Server Framework provides built-in server-only validators to enforce uniqueness, enforce related records exist and perform additional, custom operations.

SmartClient and SmartGWT have the same basic validation features so this introduction focuses on the SmartClient side. Following along with the SmartGWT Showcase should be fairly easy as well.

Using the Feature Explorer validation samples let’s take a quick tour of basic validation functionality.

Type Validation

Starting with Forms → Validation → Type, take a look at the DataSource:

<DataSource ID="type">
    <fields>
        <field name="intField" title="Integer" type="integer"/>
    </fields>
</DataSource>

This DataSource defines a single field, intField, as type “integer” with a title to show in a form or as a grid header. Where is the validator? SmartClient automatically assigns a built-in validator, isInteger, to this field based on the type “integer.” This validator just confirms that the field value is a whole number and converts any text value to a number.

The test form that uses this DataSource is simple:

isc.DynamicForm.create({
    ID: "boundForm",
    dataSource: "type"
});</pre>
<pre>isc.Button.create({
    top: 60,
    title: "Validate",
    click: "boundForm.validate()"
});

Any value can be entered into the field on the form and nothing happens until the Validate button is pressed. At that time validation is performed on all form fields – one in our case. If the validator on intField fails the form will, by default, show an error icon and provide an error message as a tooltip. There are other ways to trigger validation that will be covered later.

When assigning a specific type (FieldType) to a DataSourceField, the value is automatically converted as required before validators see it. For example, a field of type integer receives an input value typically as a string so it must be converted into a number value. Any assigned validators can then count of the value being validated as being of the correct type.

Using Built-in Validators

SmartClient provides numerous built-in validators that can be used on your fields. See ValidatorType in the reference for available validators.

Select the example Forms → Validation → Type and look again at the DataSource:

<DataSource ID="builtins">
    <fields>
        <field name="intField" type="integer" title="Integer">
            <validators>
                <validator type="integerRange" min="1" max="20"/>
            </validators>
        </field>
    </fields>
</DataSource>

Based on the details in the previous section it is clear that the field will have the isInteger validator assigned automatically. But note that another validator is attached to this field: integerRange. Additional properties, min and max, are assigned to customize this validator instance with the desired range. Neither value is required. In this case an entered value of 1 to 20 inclusive is valid.

Enter the number 27 and press Validate. Note the error is “Must be no more than 20.” This default message comes from the i18n class property Validator.mustBeLessThan. This message is special in that it can be customized based on the validator min and max properties. These properties are available as ${min} and ${max} within the message: “Must be no more than {$max}.” The validator error messages can be customized globally by changing the i18n defaults or per validator instance.

Add the property errorMessage=”Please enter a value between ${min} and ${max}” to the validator in the DataSource after max=”20” and click Try It. Again enter the value 27 and press Validate. Note the changed error message. Even though by default the validator uses two i18n messages, one for the minimum value and one for the maximum value, only one error message can be specified manually.

Value Transformation

An additional feature that a validator can provide is that of value transformation. The built-in mask validator is an example.

Select the example Forms → Validation → Value Transform and look at the DataSource:

<DataSource ID="valueTransform">
    <fields>
        <field name="phone" title="Phone" type="text">
            <validators>
                <validator type="mask"
                           mask="^\s*(1?)\s*\(?\s*(\d{3})\s*\)?\s*-?\s*(\d{3})\s*-?\s*(\d{4})\s*$"
                           transformTo="$1($2) $3 - $4"/>
            </validators>
        </field>
    </fields>
</DataSource>

The mask validator takes two properties, mask and transformTo, defining how the value is to be validated and transformed. If the value entered into this field does not match the mask regular expression an error is returned. Otherwise, the value is rewritten based on the transformTo expression.

Enter the value 123 and press Validate. Note the error “Invalid value” is returned because the mask was not matched. Try the value 1234567890 and note the field value is transformed into a formatted U.S. phone number as (123) 456 – 7890.

Built-in server-only validators

SmartClient ships with two standalone server-only validators: isUnique and hasRelatedRecord. The isUnique is used to prevent entry of a duplicate value on a field. This is checked against all records in the DataSource. Consider the case where new inventory items are added. The SKU is usually required to be unique but the user can enter any value. An isUnique validator can be assigned to prevent duplicates.

Select the example Forms → Validation → Server-based → Unique Check and look at the DataSource. In particular, note the email field:

<field name="email" type="text" required="true">
    <validators>
        <validator type="isUnique"/>
    </validators>
</field>

Here the DataSource has specified that the email field is required and must be unique. If you have followed along, you will know there are two validators assigned to this field: required and isUnique. See the matching field definition on the form:

{name: "email", required: true, validateOnExit: true},

The required property is redundant since the dataSource specifies required. It can be safely removed. Also note the validateOnExit: true property. This property causes validation of this field when focus leaves the field and the value has changed. In this sample, it lets the user know immediately if a duplicate email is entered without requiring a form validation. More on controlling validation will be covered later.

Assuming a value is entered for the email address a validation request is sent to the server. The SmartClient Server Framework takes the request and validates against the actual database that the value does not already exist. A success or failure response is returned to the client and automatically displayed. This process is seemless so the user is unaware the validation occurred server-side.

The hasRelatedRecord validator is similar. It will validate that the entered value for a field exists in a related DataSource. A validator of this type is not needed if the user must select the related value from a list but there are times when the choices cannot be limited that way. Consider a package tracking form where the user enters the tracking number to be tracked. This type of form does not fit the selection list model. Assigning a hasRelatedRecord validator will provide the user feedback required for an invalid entry.

Select the example Forms → Validation → Server-based → Related Records and look at the complaint DataSource. In particular, note the trackingNumber field:

<field name="trackingNumber" type="integer"    title="Tracking #"       required="true"   >
    <validators>
        <validator type="hasRelatedRecord"
                   relatedDataSource="masterDetail_orderHB"
                   relatedField="trackingNumber"
                   errorMessage="Tracking # does not exist" />
    </validators>
</field>

The hasRelatedRecord validator has a number of additional properties. The main two are relatedDataSource and relatedField specifying the relationship to another table. This can be compared to a SQL foreign key constraint. If the entered value is found in the related table validation is passed. You can see the masterDetail_orderHB DataSource to see where the relationship points.

As with the Unique Check sample, the server-side validation is seemless and avoids the client having to pull the full list of records to perform a local check or issuing a special fetch and processing the result.

There is one more server-only validator included with SmartClient, serverCustom, but it requires custom conditions to be defined. It is covered later.

Multiple Failing Validators

It is possible for two validators to fail for a given field. In this case, each error message is shown in the tooltip. Open the example Forms → Validation → Regular Expression and add another validator to the DataSource along with a more descriptive error message for the regexp validator:

<DataSource ID="regularExpression">
    <fields>
        <field name="email" title="Email" type="text">
            <validators>
                <validator type="lengthRange" min="10" max="64" />
                <validator type="regexp"
                           expression="^([a-zA-Z0-9_.\-+])+@(([a-zA-Z0-9\-])+\.)+[a-zA-Z0-9]{2,4}$"
                           errorMessage="Invalid email address format" />
            </validators>
        </field>
    </fields>
</DataSource>

There are now two validators on the “email” field. Click Try It, enter “abc” into the field and click Validate. The error message should include both validator messages.

Multiple messages can be prevented so that the first error found during validation stops the remaining validators from being processed. Add stopIfFalse=”true” to the lengthRange validator in the DataSource. Click Try It again to repeat your test. Note that only the length message is shown. This is the same method used by type validators discussed earlier to ignore remaining validators on failure.

In the next installment we will write and test custom validators.

Advertisement
Tags:
Follow

Get every new post delivered to your Inbox.