3

in my action class i want to have a map of strings. and in my tml i want to access this map with textfield. something like

<t:form>
    <t:textfield value="myMap['key1']"/>
    <t:textfield value="myMap['key2']"/>
...

i don't insist on syntax, but is there anything like this currently in tapestry? if not, what do i need to create such conversion in the most easy way? type coercing? custom components? i'm starting to learn tapestry so feel free to be verbose :)

piotrek
  • 13,982
  • 13
  • 79
  • 165

4 Answers4

6

Another option is to bind your own tml prefix. There is an example of binding prefixes here.

We wrote our own prefix for map which allows us to get the value in the tml like this:

${map:myMap.key1}
sloth
  • 99,095
  • 21
  • 171
  • 219
Nick
  • 76
  • 2
3

ok, i figured it out. i did a simple component MapField:

@Parameter(required=true)
Map<String, String> map;

@Parameter(required=true, allowNull=false, defaultPrefix = BindingConstants.LITERAL)
String key;

public String getMapValue() {
    return map.get(key);
}

public void setMapValue(String value) {
    map.put(key, value);
}

tml:

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
    <t:textfield value="mapValue"/>
</html>

that's it. now we can use it in other tml:

<t:mapField key="existingOrNot" t:map="myMap"/>

and in a page we need only myMap as a property:

@Property @Persist Map<String, String> myMap;

probably there are more things to be done, like passing all additional html parameters to the textfield, etc

piotrek
  • 13,982
  • 13
  • 79
  • 165
2

you will need to create an accessor method in your java class.

the most straightforward way would be to add a single method:

getMapValue(String key){...}

you can then change your tml to use

value="getMapValue('key1')"

pstanton
  • 35,033
  • 24
  • 126
  • 168
  • this way it is read only so i can't use it in a text field, can i? text field requires a setter with a single parameter - the value. so there is no place to pass the key – piotrek May 21 '12 at 10:39
1

You should be able to loop through the key set like this:

<form t:type="Form">
    <t:Loop t:source="myMap.keySet()" t:value="currentKey"> 
        <input type="text" t:type="Textfield" t:value="currentValue"/>
    </t:Loop>
</form>

You'll have to add some code in the class file that stores the current map key and gives access to the current value:

@Property
private Object currentKey;

@Persist
@Property
private Map<String,String> myMap;

public String getCurrentValue() {
     return this.myMap.get(this.currentKey);
}

public void setCurrentValue(final String currentValue) {   
    this.myMap.put(this.currentKey, currentValue);
}

(This answer is adapted from one of my earlier answers.)

Community
  • 1
  • 1
Henning
  • 16,063
  • 3
  • 51
  • 65
  • this way i have to iterate through whole map even if i want just a few keys. i also cannot add entries for keys that are not already in the map – piotrek May 22 '12 at 20:42