In most ATG operations, you update a Map property by updating a specific key value as if it were a servlet bean property:
<dsp:input type="text" bean="MyBean.value.addresses.city"/>
While addresses
is a Map property and city
is a key, this tag represents addresses
and city
as properties. Making a change to a key’s value requires entering text into a text box and submitting the operation.
In order to provide greater flexibility in updating Map properties, forms that use the RepositoryFormHandler provide access to several properties that let you manipulate Map properties like lists:
editMapsAsLists is a RepositoryFormHandler property that, set to true, lets you make changes to the Map keys and values.
keysAndRepositoryIds is a Map property that you can use to update the Map with a series of key/repository ID pairs.
keysAndValues is a Map property that you can use to update the Map with a series of primitive key/value pairs.
Note: The approach described in this section for updating Map properties applies only to the RepositoryFormHandler. For a generic approach to setting Map properties in all forms, see the Map Properties section in the Forms chapter.
editMapsAsLists
You typically interact with Maps by treating them as servlet beans. For example, to expose a value, you specify the key as an input parameter. You cannot add new key/value pairs when you work with Maps in this way.
Alternatively, you can treat a Map as a list by setting the RepositoryFormHandler’s property editMapsAsLists
to true. This lets you use dsp:input
and dsp:setvalue
tags to expose or update a Map like any list property.
To use this feature:
Make sure
editMapsAsLists
is set to true (the default setting).Set the Map’s updateMode property to
append
,prepend
,replace
, orremove
. The default value isreplace
.If
updateMode
is set toprepend
orappend
, set the Map’s numNewValues property to the number of key/value pairs you wish to add. The default is 0, specifying that new values overwrite current values.Define one or more text boxes that accept values for the Map entry to edit. The value can be a user-entered value or a page parameter that holds a
repositoryId
, which references another repository item.
For example, a page where users can enter home and work addresses might include this code:
<dsp:input type="hidden" bean="MyRepositoryFormHandler.value.addresses.numNewValues" value="2"/> <dsp:input type="hidden" bean=MyRepositoryFormHandler.value.addresses.updateMode" value="append"/> Enter Home Address: <dsp:input type="hidden" bean="MyRepositoryFormHandler.value.addresses.keys[0]" value="home"/> <br/>Street: <dsp:input type="text" bean="MyRepositoryFormHandler.value.addresses[0].street" value=""/> <br/>City: <dsp:input type="text" bean="MyRepositoryFormHandler.value.addresses[0].city" value=""/> <br/>State: <dsp:input type="text" bean="MyRepositoryFormHandler.value.addresses[0].state" value=""/> <br/>Postal Code: <dsp:input type="text" bean="MyRepositoryFormHandler.value.addresses[0].postalCode" value=""/> Enter Work Address: <dsp:input bean="MyRepositoryFormHandler.value.addresses.keys[1]" type="hidden" value="work"/><br/>Street: <dsp:input bean="MyRepositoryFormHandler.value.addresses[1].street" type="text" value=""/><br/>City: <dsp:input bean="MyRepositoryFormHandler.value.addresses[1].city" type="text" value=""/><br/>State: <dsp:input bean="MyRepositoryFormHandler.value.addresses[1].state" type="text" value=""/><br/>Postal Code: <dsp:input bean="MyRepositoryFormHandler.value.addresses[1].postalCode" type="text" value=""/>
This page supplies two sets of four text boxes, one set for home address data and identified by the key home
, and the second set for work address and identified by the key work
. Because updateMode
is set to append
, the addresses are added to the existing addresses
Map. By setting the numNewValues
property to 2
, the ATG platform creates two key/value pairs for the addresses
Map, which are populated by the values that the user provides through the form. On form submission, the new keys and values are appended to the current values to addresses
.
Note: A Map must have unique keys. If home
and work
already exist as keys in the addresses
property, their values are replaced by the new ones supplied in the form, despite the updateMode
setting.
keysAndRepositoryIds
The keysAndRepositoryIds
property lets you simultaneously set a Map key and value, where the Map holds a series of keys that map to repository IDs. Without keysAndRepositoryIds
, performing this operation requires two input tags.
<dsp:input type="text" bean="MyRepositoryFormHandler.value.favorites.keys[0] value=""/> <dsp:input type="text" bean="MyRepositoryFormHandler.value.favorites.repositoryIds[0] value=""/>
The keysAndRepositoryIds
property lets you accomplish this task with greater flexibility and power. Values saved to the keysAndRepositoryIds
property must use this format:
key=repositoryId
Note: The separator used in this example is the default value assigned to the RepositoryFormHandler’s mapKeyValueSeparator
property. You can change the recognized separator by updating the value in this property.
You can use page parameters to set dynamic key repository ID values and configure a Format
bean to provide the syntax. For example, you might want to track the brands each customer prefers. Each brand is associated with a business, and one business can maintain several brands; so you want to organize the brands by parent business. Therefore, you display the brands as text boxes. When checked, you want the favorites
Map to save a business name and brand ID as the key
and repositoryId
respectively. You might design your code like this:
<dsp:form action="keysandids.jsp" method="post"> <dsp:input bean="MyRepositoryFormHandler.value.favorites.updateMode" type="text" value="prepend"/> <br/> <dsp:droplet name="/atg/dynamo/droplet/RQLQueryForEach"> <dsp:param bean="/atg/userprofiling/ProfileAdapterRepository" name="repository"/> <dsp:param name="itemDescriptor" value="business"/> <dsp:param name="queryRQL" value="all"/> <dsp:oparam name="output"> <dsp:droplet name="/atg/dynamo/droplet/Format"> <dsp:param name="key" param="index"/> <dsp:param name="repositoryId" param="element.repositoryId"/> <dsp:param name="format" value="{key}={repositoryId}"/> <dsp:oparam name="output"> <dsp:input bean="MyRepositoryFormHandler.value.favorites.keysAndRepositoryIds" paramvalue="message" type="checkbox"/> <dsp:valueof param="message">Not set</dsp:valueof> <br/> </dsp:oparam> </dsp:droplet> </dsp:oparam> </dsp:droplet> <dsp:input bean="MyRepositoryFormHandler.update" type="submit" value="Update"/> </dsp:form>
The RQLQueryForEach
and the ProfileAdapterRepository
retrieve the brands saved as business items in the repository. Assume that each brand displays in a text box in the page and when it is modified, the Format
bean associates each business name and brand ID to the key
and repositoryId
properties of a Profile component favorites
Map.
keysAndValues
You can configure keys and values that are primitive data types for Maps with the keysAndValues
property. As with the keysAndRepositoryIds property, you do so in the context of a JSP, with a similar format:
key=value