10) Tag Transformations


Previously it was highlighted that the framework supports changes of tags in the HTML file to change the binding. This chapter demonstrates some of these tag transformations. Also we show a few examples of how the BindingInterceptor can be used to apply some special components.

10.1) Texts

This here shows some useful transformations of text inputs.

Model Code:
public String get<PropertyName>() { ... }
public void set<PropertyName>(String value) { ... }

<input type="text">
<textarea>

<label>

Paragraph

<p>

Please note that you can apply these transformations to any simple types like numbers as well.

10.2) Lists & Choices

Here we show you what you can turn combo boxes ( select tag) for arrays/collections of simple types into.

Model Code:
// either use an enum type or add a choice utility element
public <TypeOfProperty> get<PropertyName>() { ... }
public void set<PropertyName>(<TypeOfProperty> value) { ... }

<select>
<select size="8">
<input type="radio">
<input type="checkbox">
As Table
NANOSECONDS
MICROSECONDS
MILLISECONDS
SECONDS
MINUTES
HOURS
DAYS
<table>
Model Code:
// see above regarding enums, can also be an Iterable, Collection, etc
public <TypeOfProperty>[] get<PropertyName>() { ... }
public void set<PropertyName>(<TypeOfProperty>[] value) { ... }

<!-- ListMultipleChoice does not support empty
     selection once a selection was made -->
<select size="8" multiple="multiple">
Available
Selected
// Palette allows to go back to empty selection though
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createSelect(final SelectHtmlElement e) {
        if (ListsAndChoicesConstants.asMultiselectPalette.equals(e.getWicketId())) {
            return new ModelPalette(e);
        }
        return super.createSelect(e);
    }
}).bind();
<input type="checkbox">
As Multiselect Table
NANOSECONDS
MICROSECONDS
MILLISECONDS
SECONDS
MINUTES
HOURS
DAYS
<table>

10.3) Tables & Choices

You can do the same as above for arrays/collections of structured types as well, even though they are per default generated as a table.

Model Code:
// here we use the choice utility element, it can also return an Iterable, Collection, etc
public <TypeOfProperty> get<PropertyName>() { ... }
public void set<PropertyName>(<TypeOfProperty> value) { ... }
public <TypeOfProperty>[] get<PropertyName>Choice() { ... }

Default Table
Column1 Column2 Nested Action
1_1
1_2
TableRowNested[column3:1_3]
2_1
2_2
TableRowNested[column3:2_3]
3_1
3_2
TableRowNested[column3:3_3]
<table>
<select>
<select size="8">
<input type="radio">
<input type="checkbox">

Model Code:
// same as above, can also be an Iterable, Collection, etc
public <TypeOfProperty>[] get<PropertyName>() { ... } public void set<PropertyName>(<TypeOfProperty>[] value) { ... } public <TypeOfProperty>[] get<PropertyName>Choice() { ... }

As Multiselect Table
Column1 Column2 Nested Action
1_1
1_2
TableRowNested[column3:1_3]
2_1
2_2
TableRowNested[column3:2_3]
3_1
3_2
TableRowNested[column3:3_3]
<table>
<!-- ListMultipleChoice does not support empty
     selection once a selection was made -->
<select size="8" multiple="multiple">
Available
Selected
// Palette allows to go back to empty selection though
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createSelect(final SelectHtmlElement e) {
        if (TablesAndChoicesConstants.asMultiselectPalette.equals(e.getWicketId())) {
            return new ModelPalette(e);
        }
        return super.createSelect(e);
    }
}).bind();
<input type="checkbox">


10.4) Tables & Panels

Despite the above table transformations, arrays/collections of structured types can also display rows as panels. Just create a panel for the row class and apply the below transformations on the table.

Model Code:
// can also return an Iterable, Collection, etc
public <TypeOfProperty>[] get<PropertyName>() { ... }

Default Table
Column1 Column2 Nested Action
1_1
1_2
TableRowNested[column3:1_3]
2_1
2_2
TableRowNested[column3:2_3]
3_1
3_2
TableRowNested[column3:3_3]
<table>
Model Code:
// no static typing required in model, thus we can even have different panels in it as demonstrated below
// though you can also stick to the code above and use only one panel
public List<?> get<PropertyName>() { ... }
As Unordered List
<!-- this just puts a panel for each
     element beneath one another -->
<ul>
As Collapsible
// collapsibles are panels that can be opened/closed
// all panels can be open at the same time
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createTable(final TableHtmlElement e) {
        if (TablesAndPanelsConstants.asCollapsible.equals(e.getWicketId())) {
            return new ModelCollapsibleList(e);
        }
        return super.createTable(e);
    }
}).bind();
As Accordion
// a special type of collapsibles where 
// only one panel can be open at a time
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createTable(final TableHtmlElement e) {
        if (TablesAndPanelsConstants.asAccordion.equals(e.getWicketId())) {
            return new ModelAccordion(e);
        }
        return super.createTable(e);
    }
}).bind();
As Tabbed
// we can even turn it into a TabbedPanel easily
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createTable(final TableHtmlElement e) {
        if (TablesAndPanelsConstants.asTabbed.equals(e.getWicketId())) {
            return new ModelTabbedPanel(e);
        }
        return super.createTable(e);
    }
}).bind();

10.5) Tabbed & Panels

You can also apply the same panel transformations as above to @Tabbed models instead of tables.

Model Code:
@Tabbed
public <TypeOfProperty> get<PropertyName>() { ... }

Default Tabbed
<!-- div and span work also, but iframe is the default 
     to differentiate it better -->
<iframe>
As Unordered List
Distance In KM From To 
384,403
Earth
Moon
384,403
Moon
Earth
<ul>
As Collapsible
Distance In KM From To 
384,403
Earth
Moon
384,403
Moon
Earth
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createTabbed(final ITabbedHtmlElement<?, ?> e) {
        if (TabbedAndPanelsConstants.asCollapsible.equals(e.getWicketId())) {
            return new ModelCollapsibleList(e);
        }
        return super.createTabbed(e);
    }
}).bind();
As Accordion
Distance In KM From To 
384,403
Earth
Moon
384,403
Moon
Earth
new GeneratedBinding(this).addBindingInterceptor(new BindingInterceptor() {
    @Override
    public Component createTabbed(final ITabbedHtmlElement<?, ?> e) {
        if (TabbedAndPanelsConstants.asAccordion.equals(e.getWicketId())) {
            return new ModelAccordion(e);
        }
        return super.createTabbed(e);
    }
}).bind();

10.6) Links

Here we show you how to transform links into other things. In the model code, links are just action methods with special return types as demonstrated below.

Model Code:
public File <ActionName>() { ... }

<a>
<iframe>
<img>

Model Code:
public IResource <ActionName>() { ... }

<iframe>
<img>

Model Code:
public ResourceReference <ActionName>() { ... }

<iframe>
<img>

Model Code:
public String <ActionName>() { ... }

<iframe>
<img>

Model Code:
public URI <ActionName>() { ... }

<a>
<iframe>
<img>

Model Code:
public URL <ActionName>() { ... }

<a>
<iframe>
<img>

Model Code:
public Url <ActionName>() { ... }

<a>
<iframe>
<img>

Keep in mind that you can make anchor tags look like links by removing the btn bootstrap css classes on them. You can even transform them to button tags if you want. The same applies vice versa to convert button tags into anchors. Also image files are not the only things you can link to, it works with any resource, but does not make logical sense everywhere. For example a link to an external website or a pdf file can be used as an iframe, but makes no sense as an image tag.