The tools and sample stores shipped with WebSphere Commerce Versions 5.4 and 5.5 use a subset of the possible list of user registration attributes. This article describes how to extend the store-front and tools registration pages to support additional attributes provided out of the box and how to define and use custom attributes.
The list of supported attributes for the user registration flow is available from the online help by searching for "UserRegistrationAdd command" and "UserRegistrationUpdate command". The online documentation lists which attributes are mandatory, and contains a complete list of attributes provided out of the box. The out of the box attributes are fields from the following database tables:
The store models shipped with WebSphere Commerce 5.5 and the sample stores in WebSphere Commerce 5.4 all use a subset of these attributes. If you want to customize the registration form with attributes that are not in the samples, then first check to see if what you want is already in the list of attributes provided.
If you have a specific requirement, and cannot find an attribute from the list that is suitable to map for your use, then you can create a custom attribute. You can define custom attributes without making any changes to the code by updating a database table and adding the new parameter to the URL request invoked from your JSP.
Defining custom attributes
You can define custom attributes using the MBRATTR and MBRATTRVAL tables. The MBRATTR table supports the definition of custom attribute types. The MBRATTRVAL table is where the values for these custom defined attribute types get persisted.
To define a custom member attribute, add the entry to the MBRATTR table. The fields of the MBRATTR table are:
|MBRATTR_ID||Primary key of this MBRATTR table.|
|ATTRTYPE_ID||Type of the member attribute. Foreign key to ATTRTYPE table.|
|NAME||Name of the member attribute.|
|DESCRIPTION||Description of the member attribute.|
Let's assume that you want to create a new attribute called "corporateemail." This is a string representing the user's internal email account. You can create the entry in the MBRATTR table as follows:
insert into MBRATTR values ((select min(mbrattr_id) - 10000 from mbrattr),'STRING', 'corporateemail',NULL)
Now that you have the custom attribute, you can use it in the registration flow. The values for these attributes are stored in the MBRATTRVAL table:
|MBRATTRVAL_ID||Primary key for this table.|
|STOREENT_ID||The store entity to which this attribute value for this member applies.|
|MEMBER_ID||The member to which this attribute value applies. Foreign key to the MEMBER table.|
|ATTRTYPE_ID||Type of the member attribute value. Foreign key to the ATTRTYPE table.|
|MBRATTR_ID||The attribute that this value is associated with. Foreign key to the MBRATTR table.|
|FLOATVALUE||If the type of the attribute value is FLOAT, this column holds the attribute value. If the type is not FLOAT, this column is NULL.|
|INTEGERVALUE||If the type of the attribute value is INTEGER, this column holds the attribute value. If the type is not INTEGER, this column is NULL.|
|STRINGVALUE||If the type of the attribute value is STRING, this column holdsthe attribute value. If the type is not STRING, this column is NULL.|
|DATETIMEVALUE||If the type of the attribute value is TIMESTAMP, this column holds the attribute value. If the type is not TIMESTAMP, this column is NULL.|
Depending on the type of the attribute, the attribute value will go in the corresponding field.
Using custom attributes in the registration flow
The descriptions of the user registration commands (Add and Update) in the online help describe how to add custom attributes to the command request. Ensure that the attributes are defined in the MBRATTR table, then you can use them by adding parameters to the request in the following format:
attributeName matches the NAME field in the
MBRATTR table, the storeName is the
of the store (from the STOREENT table). The action is either "a" for add,
"r" for replace, or "d" for delete. The number is an attribute that you
can use to store multiple values for the same attribute.
Let's look at some examples.
Example 1: corporate email
This example is the corporate email attribute created earlier. To add a corporate email value, add the following parameter:
This creates an entry in the MBRATTRVAL table with the value
myemail in the STRINGVALUE field.
Example 2: corporate email, store specific
This example uses the same attribute, but now you can store it in a store dependent way. This is useful if you want to capture different values for the same attribute, depending on the store.
This again creates an entry in the MBRATTRVAL table with the value
myemail in the STRINGVALUE field, but it also
adds the store identifier of 10001 to the STOREENT_ID field.
Example 3: corporate email, multi-valued
This example again builds on the previous example, but it supports multiple values for the same attribute.
This creates two entries in the MBRATTRVAL table. The first storing of
myemail in the STRINGVALUE field, and the
second storing of
myemail2 in the STRINGVALUE
Customizing store pages
To take advantage of some of the fields not leveraged by the out-of-the-box models, or to use custom attributes, such as those described in the previous section, the requirement for the store-front customization is purely at the JSP level. Add the additional fields to your page, and pass them to the user registration commands.
Customizing Accelerator pages
Assuming you have customized the store-front registration pages to support the attributes required by your organization, you may wish to make the same customization in the WebSphere Commerce tooling. This last section describes how to customize the Accelerator customer update wizard to support additional attributes.
The Accelerator feature is based on the WebSphere Commerce tools
framework, which provides a number of reusable widgets for Web-based tools
development. The customer update feature, which is what you want to
customize, is implemented as a multi-panel wizard. After selecting a
customer, the customer service representative (CSR) navigates through the
four panels (General, Address, Contact, and Demographics) to update
information about the customer. Each of these four panels is implemented
as a Java Server Page, which caches the values filled in by the CSR such
that the properties from all four pages are bundled and passed through to
the underlying command
CSRCustomerInfoUpdateCmd) when the update is
submitted. This invokes the registration update command,
The default implementation of the
CSRCustomerInfoUpdateCmd is expecting only a
subset of the attributes supported by the real registration command. If
you want to define additional attributes, you either override the command
or use the approach described in the remainder of this section to flag
your additional properties so that they will be passed through
UserRegistrationAdminUpdateCmd. The latter
option is only available with WebSphere Commerce 5.4 Fixpack 6 or later,
and WebSphere Commerce 5.5 Fixpack 3 or later. If you are using WebSphere
Commerce 5.4 or 5.5 prior to these fixpack levels, contact WebSphere
Commerce support to request this feature as an APAR.
To pass through your own attributes, in addition to those supported by the default Accelerator pages, add them to one of the existing property objects in the JSP, with a prefix of "ext_" in the name. The following example shows how to update the PropertyProfile.jsp to support the userProfileField1 attribute.
Figure 1 displays the default Accelerator user profile page, with the added userProfileField1.
Figure 1. Accelerator pages with an additional attribute model
The underlying JSP for this page is called PropertyProfile.jsp. To get the additional field, add the following immediately above the section where the last visit is displayed:
<TR> <TD> User profile field1: <INPUT size="20" type="text" name="ext_userProfileField1" maxlength="254"> </TD> </TR>
This creates the textbox, and captures the result in the
ext_userProfileField1 variable. Note that the
userProfileField1 attribute is one of the parameters supported by the
UserRegistrationAdminAdd command. You use the "ext_" prefix to inform the
tools framework command that this is an extension attribute and it should
be passed through to this command.
The next step is to update the
function in the JSP to ensure that the value for this new variable is
saved as the user navigates across panels. Insert this code snippet after
the other updates to the profileInfo object:
profileInfo.ext_userProfileField1 = document.profile.ext_userProfileField1.value;
The profileInfo object is locally defined, and is converted by the tools
framework into an XML format and passed on to the underlying command. You
can implicitly define the
field of the object, and assign to it the value captured from the field
created above. When the user types data into the user profile field1 field
on the form, that data is copied into the local profileInfo object.
The tools page has logic that can determine precisely what aspects of the
user profile have been updated, such that unchanged data is not passed on
to the registration command. You need to update this logic for any changes
that might happen to the new field. Update the
compare() function in the JSP:
This code goes through each variable on the page (the object "e" that
appears in this code snippet is the current attribute) and checks against
the defined criteria to determine if the page has been updated. In this
case, the attribute of interest has the name of
ext_userProfileField1, and the value that you
want to compare it against is the field1 attribute from the user profile
table. It is available from the databean using the
getUserProfileField1() method. If the value on
the page is different from the value cached in the bean, then you know the
value has been updated so set the flag for
userRegUpdated to true.
If you are adding your own custom attributes, keep the following update flags in mind:
- certStatusUpdated (WebSphere Commerce 5.4 only)
You can also put the following XML objects in your attributes:
- profileInfo (the one used in this example)
Because there is no direct mapping between the update flags and the data objects, the underlying logic passes through any extension attribute to the registration command. The one exception is that extension attributes in the addressInfo if the addressUpdated flag is set. The address updates are fairly complex operations, and you do not want to do it unless it is absolutely necessary. The updates to the other tables are relatively trivial, and pushing back the same data is not an issue.
There are a few minor changes to make to the JSP, for managing the state
as the user navigates through the panes. The first one is to update the
initializeState() function. This function has a
decision point at the entry to determine if it is the first update, or a
subsequent update. Add the following code for the state information that
has already been initialized. For example, the user is navigating between
document.profile.ext_userProfileField1.value = profileInfo.ext_userProfileField1;
This copies the form field value into the local object.
Within the same method, also update to initialize the page for the first time:
This is the logic that ensures that the form field picks up the value from the database on the first time into the page. Now the user can navigate between panes, and update any attribute.
You can do everything that has been described in this article without making changes to the registration commands. To add custom member attributes to the store front registration pages, add the new attribute definition to the database and update the JSP to pass the values to the command. To extend the Accelerator user profile pages, you can update the JSPs using the technique described.
The authors would like to thank Anthony Tjong for his inspiration and guidance in the writing of this article.