You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@click.apache.org by Bob Schellink <sa...@gmail.com> on 2009/12/15 07:17:23 UTC
Renderable property
Hi all,
One of the areas where Click can be confusing is when dynamically creating/adding controls to a Page
or container. The problem is quite apparent when trying to create and add controls from within a
control's action event. Since Click has a predefined event flow (onInit, onProcess, onRender), this
can easily lead to the new control being instantiated after crucial events have fired, such as
onInit, onProcess etc. A simple workaround is to manually fire these events upon creation eg:
control.onInit();
But this isn't obvious for new users. I normally suggest that all controls be created up front so
they participate in the full event flow. Then instead of adding the controls one can remove the ones
not needed at that time.
However this doesn't feel natural and creates more problems when working with stateful pages, since
the controls have to be re-added.
So how about we add a new Control method (isRenderable/setRenderable or isVisible/setVisible) which
controls whether the Control is rendered or not. Thus all controls can be created/added at design
time and partake in all Click events, but their rendered state is controlled at runtime.
Expected usage:
public MyPage extends Page {
private Form form;
public MyPage() {
form = new Form("form");
form.add(new TextField("name") {
public boolean isRenderable() {
return isCompany();
}
});
form.add(new TextField("firstname") {
public boolean isRenderable() {
return !isCompany();
}
});
form.add(new TextField("lastname") {
public boolean isRenderable() {
return !isCompany();
}
});
}
private boolean isCompany() {
Object entity = mydao.load(Entity.class, "123");
if (entity instanceof Company) {
return true;
} else {
return false;
}
}
}
In the example above we either render the "name" field or firstname+lastname fields depending on
whether the domain entity is a Company or a Person.
The isRenderable property can be used by the Control and/or Container to determine if it should be
drawn. getHeadElements implementations can also check this property whether to include JS/CSS:
public MyControl extends AbstractControl {
public void render(HtmlStringBuffer buffer) {
if (!isRenderable()) {
return;
}
...
}
public List getHeadElements() {
if (!isRenderable()) {
return new ArrayList(0);
}
...
}
}
The property can also be used in Velocity templates:
#if($form.isRenderable())
$form
#end
Good idea/bad idea? What do you think?
kind regards
bob