|
Custom components
You already have seen some Wicket components in action. You also learned that
you can influence what the components actually do by providing them with
proper models. Now it is time to look at how to customize Wicket components.
Extending
Usually you do not want to start from scratch when you customize a component.
Most components can be extended, and have methods that are explicitly meant
for customization.
Some components do not even work without this, like wicket.markup.html.link.Link, which has abstract
method onClick, or wicket.markup.html.list.ListView that has abstract method populateItem.
Component wicket.markup.html.form.DropDownChoice is a non-abstract component, but by extending it, we can alter
its behaviour. For example, look at:
add(new DropDownChoice("venueSelect", new PropertyModel(this, "currentVenue"), getVenueDao().findVenues()) { protected boolean wantOnSelectionChangedNotifications() { return true; } });
By overloading method wantOnSelectionChangedNotifications, and have it return
true (instead of false which is the default), an onchange javascript event
handler will be generated, so that on each new selection of the dropdown, a
roundtrip will be made to the server, updating the model of the dropdown
component. And if you used your models smart enough, this can have the effect
that other components have an updated rendering as well.
And if we want to customize the component even further, we could do:
add(new DropDownChoice("venueSelect", new PropertyModel(this, "currentVenue"), getVenueDao().findVenues()) { protected boolean wantOnSelectionChangedNotifications() { return true; }
protected void onSelectionChanged(Object newSelection) { } });
and do something nice in the ''onSelectionChanged// event handler.
By making use of models that use e.g. a shared property, we can do all kinds
of neat things. Here is an example:
add(new DropDownChoice("venueSelect", new PropertyModel(this, "currentVenue"), getVenueDao().findVenues()) { protected boolean wantOnSelectionChangedNotifications() { return true; } }); WebMarkupContainer container = new WebMarkupContainer("rolesListContainer") { public boolean isVisible() { return getCurrentVenue() != null; } }; add(container);
Note that we fed our dropdown with a property model that works on this (e.g. a
Page) using property 'currentVenue'. Now, with the second component we
override method isVisible, and use that same property 'currentVenue' for our
evaluation.
If any venue is selected, we'll display the container and anything that is
nested on it. If no venue is selected, we do not display anything. This is a
very handy trick to switch parts of your page on and off, and as the dropdown
will generate a roundtrip on each selection, our page will feel very dynamic.
TODO... write more
AttributeModifiers
TODO
Panels and Borders
See also
Panels_and_borders
Both Panels and Borders have their own markup file, but the markup is used in
different ways:
The Border component inserts markup before and after its child components.
<html> <body> <div wicket:id="myBorder"> <!-- Border markup --> <span wicket:id="myContent">content</span> <!-- Border markup --> </div> </body> </html>
The Panel component inserts markup into the body of the tag.
<html> <body> <div wicket:id="myPanel"> <!-- Panel markup --> </div> </body> </html>
See
Panel
for more information.
|