Rule-based Validation of a Single K2 SmartForms Control

K2 SmartForms controls are validated in two ways: One is immediate, and the other is rule-based. But the rule-based validation applies to an entire form, not to a specific control.

But does it have to be that way?

As I mentioned above, K2 SmartForms controls are validated in two ways.

The first is by setting a specific validation measure on the control. There’s a validation section in the control’s properties. On a textarea control, for example, you can set a length limit or use REGEX against a pattern. You can also set a message to be displayed if the value in the control violates the validation measures you’ve specified. This method triggers the moment the violation occurs:

Control Validation
The value in the recipients textarea control failed validation.

The second is through the use of rules. The “if the Form passes validation” condition must be configured to include specific controls. Configuration allows for two methods of validation: as a required control (that is, requiring the field has a value), and as having a valid value, according to the validation conditions you’d specified in the former method. Since this validation is rule-based, it will get triggered when the rule is executed.

The rub is, there isn’t a way to use those rules to trigger validation of a single control…

…or is there?

Given: an e-mail form with multiple controls. The user is expected to provide data on the recipients, a subject line, and a body. The form also has a data label for reporting status, one button for sending the message, and one button for resetting the form:

A simple email form
A simple form with a textarea control, two textboxes, a pair of buttons, and a data label to report status (not shown).

Now let’s say the send button is only enabled when all fields are valid. Yes, you can do this by including the aforementioned “if the Form passes validation” condition in the click event rule, but what if you wanted the user to have a visual indication that their input is valid in each control as soon as each control is changed?

Simple e-mail form
The value in the recipients textarea is valid, and the status label at bottom confirms it. The send button is disabled until all form controls are valid.

Hmm… can’t really do that out-of-the-box. Control-level validation occurs at runtime as each control is changed, but the only indication of the value being valid is… when nothing happens. The user gets a prompt when the input is invalid, not when it’s valid. And form-level validation can be fired using a rule condition, but no rule events exist for “if the control passes validation.”

Well, we can actually still use a combination of both of those tests to manufacture rule-based control-centric validation. All we need is a little imagination and some quality time in the rules engine.

The secret sauce is in the configuration of the “if the Form passes validation” condition. At the bottom of the configuration form are two checkboxes:

Validate only the control you want by disabling the other controls earlier in the rule.

Notice the checkbox beside the phrase, “Do not validate hidden, disabled or read-only controls, Views and tabs.”

Put simply, you can achieve validation of a single form control if you disable all of the controls on the form except the one you’re working with inside of the rule, then add the “if the form passes validation” condition and whatever the actions are, then re-enable all of the form controls by the end of the rule.

Here is an example of such a rule:

Changed event rule for the textarea control
Disable the other form controls before the validation condition is executed; reenable those controls before the end of the rule.

The last action in the rule is to run a rule called “Four Checks to Activate Send Button.” As you might guess, this rule checks the number of validated controls. If all are valid, the Send button is exposed so the user may send the message.

Now repeat for the changed() event rules for each of the form controls. And don’t forget to call that last rule, so the form can unlock that send button!