- Why develop a new Web Application Framework?
-
Because the existing frameworks did not meet my needs. Struts doesn't really do much,
while Tapestry is too complicated.
For a more comprehensive answer please see Why Click.
- How can the GUI designer define the HTML if Click Controls generates everything?
-
In Click there is nothing preventing you from laying out HTML forms by hand.
It just provides the option of doing it automatically for you.
There are a number of approaches you can use for generating for HTML,
each with pros & cons:
-
Use Click forms and controls to do all the HTML rendering for you.
This a 80/20 approach where you can quickly get stuff developed, but it may
not meet all your UI style requirements.
Please note the Forms control provides many
auto layout
options, see the click-examples 'Form Properties'
for a demonstration.
The Form control also renders the class attributes 'form', 'fields', 'errors' and 'buttons'
in the form's HTML elements enabling fine grained CSS control.
As an example you could configure a form to display the labels on top, and want to
increase the vertical spacing between fields. To do this simply define the CSS
style in front of your form:
<style type="text/css">
td.fields { padding-top: 0.75em; }
</style>
$form
Fields are also rendered with an 'id' attribute enabling manipulation of individual fields.
-
Subclass Click Form/Controls to customise HTML rendering.
This is a good approach for ensuring a common LAF across your web application,
but you will have to get your hands dirty and write some code.
-
Use Velocity macros for a generic HTML layout.
This is easy to do and gives you good reuse across your web application.
Please see the Form
velocity macros
example, and also see the click-examples 'Velocity Macro'
demonstration.
-
Layout your HTML forms by hand.
This gives you the ultimate control in presentation, but provides no reuse
across your web application.
Please see the Form
manual layout
example.
- How can I have many Pages using the same HTML template?
-
To do this use the Page templating technique detailed in the
Page Templating topic.
Page templating is highly recommended for your web applications, as it provides
numerous benefits including:
- greatly reduces the amount of HTML you need to maintain
- ensures you have a common look and feel across you application
- makes your application more robust, as there is less code to test
For a live demonstation of page templating deploy and run the
click-examples application.
- Can you exclude some fields from a Form?
-
To exclude some fields from being displayed in a shared Form class use the
Form.removeFields()
method.
You can even do this in your page template. Just make sure you call you call
it before $form renders itself. For example:
$form.removeFields(["field11", "field15", "field22"])
$form
- How do you internationalize Pages and Control labels?
-
Click provides good string localization support for internationalization requirements.
The Page class supports page specific string localisation bundles using the
method
getMessage(String).
For example a Login class with three locale string property files on the classpath:
/com/mycorp/pages/Login.properties
/com/mycorp/pages/Login_en.properties
/com/mycorp/pages/Login_fr.properties
The Field control classes share a common string properties file:
/click-control.properties
The field class provides a number of
getMessage(String)
methods which support localized strings and message formatting.
Please also see the Control topic Message Properties.
- How do you create an ActionLink with several parameters?
-
If you need to have an ActionLink with several parameters create a composite
parameter and pass this to the ActionLink. For example:
#set ($id = $customer.id + "-" + $account.id)
<a href="$deleteLink.getHref($id)"
onclick="return window.confirm('Please confirm to delete this account.');">
<img src="images/delete.gif" title="Delete" border="0" align="middle">
</a>
In your ActionLink onClick handler method parse out the two parameter values.
For example:
public boolean onDeleteClick() {
String value = deleteLink.getValue();
int index = value.indexOf("-");
Long customerId = Long.valueOf(value.substring(0, index));
Long accountId = Long.valueOf(value.substring(index + 1));
// Delete customer account
..
return true;
}
- How can you integrate Click into Spring?
-
The ClickServlet can be subclassed to support applications using Inversion
of Control (IoC) frameworks such as Spring and HiveMind.
To integrate Spring with Click you can subclass the ClickServlet and override the
newPageInstance()
method to use Spring to create Page objects and set their dependencies.
For example:
public class SpringClickServlet extends ClickServlet {
/** Spring bean factory. */
protected BeanFactory beanFactory;
/**
* @see ClickServlet#init()
*/
public void init() throwsServletException {
super.init();
beanFactory = new XmlBeanFactory(new ClassPathResource("spring-beans.xml"));
}
/**
* @see ClickServlet#newPageInstance(String, Class)
*/
protected Page newPageInstance(String path, Class pageClass) throws Exception {
String beanName = path.substring(0, path.indexOf("."));
Page page = (Page) beanFactory.getBean(beanName);
if (page == null) {
page = (Page) pageClass.newInstance();
}
return page;
}
}
In this example the Spring bean name is derived from the Page path,
so the request of "/security/login.htm" would map to a bean name of
"/security/login". If a corresponding Spring Page bean could not be found a
new Page instance is created from the pageClass.
The Page.onDestroy()
method can then be used to free any allocated resources to a Page object.
The Spring Web MVC Framework however, is not compatible with Click. The Spring framework
uses a low level command pattern design like Struts and WebWork.
Spring uses a DispatcherServlet to route requests to Controller
objects and then passes the ModelAndView results to the rendering layer.
public interface Controller {
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception;
}
In Spring MVC the integration plugin points are the Controllers.
Click uses higher level design constructs focusing on Pages and Controls. Click uses its
own ClickServlet for dispatching requests to Pages and Controls,
which are Click's plugin points.
- Why not use FreeMarker instead of Velocity?
-
FreeMarker was evaluated against Velocity for template rendering,
and has some features Velocity doesn't. However Velocity was
chosen over FreeMaker because it doesn't use an XML based
syntax, so its easier to read, and because Velocity is easier
to learn.
One of FreeMarker's strong points compared to Velocity is error reporting.
This issue is addressed in Click by using a custom Velocity 1.5 build
to provided enhanced error reporting.
Click will render the source code with the error. For example: