Technical Blog

1 Post tagged with the tag tag

Give them an inch, they take a mile. Any time you give users the ability to enter free form text, there's a potential for something to go wrong. Thankfully, we've already got a variety of pieces in Elastic Path Commerce to validate user input. As of 6.1.2., the Not authorized to view the specified document 1262 includes a validation feature, so when users are creating Dynamic Content Delivery rules, the condition builder dialog can provide instant feedback and prevent them from submitting invalid values. To see this in action, fire up the CM client, go to the Store Marketing activity, and edit a Dynamic Content Delivery. When you get to the SHOPPERS screen (Step 4 of 6), add the "have a cart subtotal" tag. The tag requires a numeric value. If you try to enter alphabetical or special characters, the text field turns red. If you click the red x next to the field, you'll see an explanation of the error.

tag-validation.png

 

If you're creating your own tag definitions, you'll want to learn how to incorporate tag validation. Since I like to learn by doing, I gave it a try, and in this article, I'll walk you through the steps I followed to define a tag, capture values for it, and enable validation on it.

 

Before diving in, I should provide a very brief overview of how tag validation works. When you create a tag definition, you associate it with a tag value type. You can think of a tag value type as high-level data type. For example, in 6.1.2, there are over a dozen out-of-the-box tag value types, including time, age, gender, text, money, city, product category. Each tag value type has its own set of validation constraints, which determine whether a given value qualifies as a valid instance of that type. For example, the default validation constraints for the age tag value type require the value to be a number between 0 and 120. The validation constraints are used most notably in the Dynamic Content Delivery wizard, to ensure that users enter sensible values when creating SHOPPER segment conditions. Behind the scenes, we use Spring Validation (or Valang) to interpret the validation constraints. We'll look a bit more at this later on, since this is probably the most interesting part of it.

 

The first thing I needed to do was to decide what kind of tag I wanted to create. For the purpose of testing validation, I figured a phone number tag might be a good one to try. I created a tag value type in the database (identified by the GUID phone_number) and specified the operators it needed to support.

insert into TTAGVALUETYPE(uidpk, guid, java_type)
     values(17, 'phone_number', 'java.lang.String');

insert into TTAGVALUETYPEOPERATOR(tagvaluetype_guid, tagoperator_guid)
     values('phone_number', 'includes'),
          ('phone_number', 'greaterThan'),
         ('phone_number', 'lessThan'),
          ('phone_number', 'notIncludes');

Then, I created a basic validation constraint.

insert into TVALIDATIONCONSTRAINTS(uidpk, object_uid, error_message_key, validation_constraint, type)
     values(17, 17,     'validationTagPhoneNumberError', 
     '{ condition : isValidConditionType(this) is true AND match(\'[0-9]\\\\d{2}-\\\\d{3}-\\\\d{4}\', tagValue) is true : \'value must be a valid phone number (only numbers)\' }',
     'TagValueType');

Okay, that might look a bit scary. The object_uid and type columns together identify the tag value type (the uidpk in the TAGVALUETYPE table). The validation_constraint column contains the interesting part. The format of the validation constraint is as follows:

{ condition: <constraint> : <error message> }

The first part of the constraint, isValidConditionType(this), checks to make sure the value is not null, that its Java type matches the tag value type's Java type, and a few other checks. As a rule, you should always include this in your constraints.

 

The second part is where it gets interesting. If you remove some of the escape sequences, you're left with a condition that includes a simple regular expression to match North American telephone numbers.

match('[0-9]\\d{2}-\\d{3}-\\d{4}', tagValue) is true

match is a Valang function that returns true if the string in the second argument matches the regular expression in the first argument. The tagValue is a placeholder for the value that's being evaluated. There are a number of other functions available in Valang and you'll want to get familiar with them by reading the Valang documentation, but the syntax is pretty straightforward.

 

The last step for setting up the validation constraint is to create a localized error message for it.

insert into TLOCALIZEDPROPERTIES(uidpk, object_uid, localized_property_key, value, type)
     values(100174, 17, 'validationTagPhoneNumberError_en',
        'The phone number must match the format XXX-XXX-XXXX',
        'TagValueConstraint');

 

With this in place, I could define tags and set their tag value type to phone_number. To demonstrate that it worked, I created a customer telephone number tag, attached it to the SHOPPER tag dictionary, and then went into the Dynamic Content Delivery dialog to try it out.

invalid-phone-number.png

When I tried to enter letters or special characters other than the dash, the field background turns red and I could click the x to find out what I'd done wrong.

 

This is just a simple example. A quick look at the Valang documentation will reveal how flexible and powerful it is. I was also really surprised at how easy it was to set up a tag value type and associate it with validation constraints. In an upcoming article, I'll take things one step further and show how to replace the tag value's free-form text box with a drop-down list or combo box.

0 Comments Permalink