Aranea supports JSP rendering by providing a JSP 1.2 custom tag
library that tries to abstract away from HTML and allow programming in
terms of widgets, layouts and logical GUI elements. The tag library URI is
"http://araneaframework.org/tag-library/standard" and it is contained in
aranea-presentation.jar
, so putting this JAR in the
classpath (e.g. WEB-INF/lib
) is enough to put it to
work. Library tags support JSP Expression Language that is used in JSTL
1.0.
Aranea examples use JSP XML form and in such form importing the library should look like this:
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://araneaframework.org/tag-library/standard" version="1.2">
...
</jsp:root>
In a usual JSP file it should look like this:
<%@ taglib uri="http://araneaframework.org/tag-library/standard" prefix="ui" %>
...
The suggested prefix for the tag library is "ui".
There is otherwise identical taglib that has <rtexprvalue>
set to true
for each tag attribute. URI for that taglib is http://araneaframework.org/tag-library/standard_rt
.
When using JSP version 2.0 or higher, this taglib should be used, otherwise EL in attributes is rejected by
containers.
Aranea JSP rendering should start from some root JSP (root template) that will include the root widget(s) (which typically are some kind of flowcontainers or menus). To support widgets and other custom tags one needs to make sure that the template looks something like this:
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:ui="http://araneaframework.org/tag-library/standard" version="1.2">
<ui:widgetContext>
<html>
<head>
<title>Aranea Template Application</title>
<ui:importScripts/>
<ui:importStyles/>
</head>
<ui:body>
<ui:systemForm method="POST">
<h1>Aranea Application</h1>
<ui:messages/>
<ui:widgetInclude id="root"/>
</ui:systemForm>
</ui:body>
</html>
</ui:widgetContext>
</jsp:root>
Next are described all these tags except <ui:widgetInclude>, which is described in the following section.
Aranea comes bundled with different external resources: javascript
libraries, stylesheets and images. To automate the process of loading
the javascript files without the manual copying of them to specific
webapp locations, a special filter is used. The filter is able to read
files from aranea jar
files.
<ui:importScripts> depends on the filter StandardServletFileImportFilterService being set. The filter provides the functionality of reading files from the jars on the server.
If no attributes specified, the default group of javascript files are loaded.
Attribute | Required | Description |
---|---|---|
file | no | Writes HTML <script> tag to
load the specific file. |
group | no | Writes HTML <script> tag to
load a group of javascript files. |
Aranea comes bundled with CSS files to provide custom look for different predefined components (the template app, calendar, htmleditor, etc.). Just as with javascript, to use them one would have to extract them from the jars and use them just like any other css file would be used. To automate this process with aranea css files one can use the <ui:importStyles> tag to include the css files automatically.
<ui:importStyles> depends on the filter StandardServletFileImportFilterService being set. The filter provides the functionality of reading files from the jars on the server.
If no are attributes specified, the default group of css files are loaded.
This tag will render an HTML <body> tag with Aranea JSP specific onload and onunload events attached. It usually writes out some other page initialization scripts too, depending on the circumstances. It must be present in a JSP template, otherwise most client-side functionality will cease to function.
Attribute | Required | Description |
---|---|---|
onload | no | Overwrite the standard Aranea JSP HTML body onload event. Use with caution. |
onunload | no | Overwrite the standard Aranea JSP HTML body onload event. Use with caution. |
id | no | HTML BODY id. |
dir | no | HTML BODY dir attribute. |
lang | no | HTML BODY lang attribute. |
title | no | HTML BODY title attribute. |
This tag will render an HTML <form> tag along with some Aranea-specific hidden fields. When making custom web applications it is strongly suggested to have only one system form in the template and have it submit using POST. This will ensure that no matter what user does no data is ever lost. However Aranea does not impose this idiom and one may just as well submit using GET, define system forms in widgets and use usual HTML links instead of JavaScript. See Section 4.2, “System Tags” for usage example and Section 3.5.20, “System Form Field Storage Filter” about a filter that provides some essential hidden fields.
Attribute | Required | Description |
---|---|---|
id | no | The HTML "id" of the <form>
tag that may be used in JavaScript. It will be autogenerated
if omitted. |
method | yes | HTTP submit method, either GET or
POST . |
enctype | no | Same as HTML <form> attribute
enctype , defines how form data is
encoded. |
This tag will render messages of given type if they are present in
current MessageContext
. When type is not specified,
all types of messages are rendered. As MessageContext
is typically used for error messages, it is common to render these
messages somewhere near top of the page, where they can easily be
spotted.
Attribute | Required | Description |
---|---|---|
type | no | Message type. |
styleClass | no | CSS class applied to rendered messages, default being
aranea-messages . |
divId | no | Sets the id of the HTML <div> inside which the messages are rendered. If left unspecified, no id is assigned. |
style | no | CSS inline style applied to rendered messages. Use styleClass instead. |
Defines an attribute of the containing element, where possible. See also Section 4.3.3, “<ui:element>”. Most form element tags accept attributes set by this tag too, see the section called “Examples”.
Attribute | Required | Description |
---|---|---|
name | yes | Attribute name. |
value | yes | Attribute value. |
Defines an HTML element content, meaning the body of the HTML element where text and other tags go.
Defines HTML node, can be used together with
<ui:attribute>
and
<ui:elementContent>
to define a full HTML
node.
Attribute | Required | Description |
---|---|---|
name | no | HTML element name. |
Registers a simple javascript keyboard handler.
Attribute | Required | Description |
---|---|---|
scope | no | When a keyboard event happens, it is usually associated with a certain form element / form / widget / etc. The object with which an event is associated is identified by a hierarchical id (e.g. there may be widget 'somelist', containing form 'somelist.form', containing textbox 'somelist.form.textbox'. The scope is a prefix of that id that must match in order for the handler to be triggered. For example, the handler with scope='somelist.form.textbox' will be triggered only when the event in the textbox occurs, but the handler with scope="somelist" will be triggered when any event in any of the elements inside any of the forms of "somelist" occurs. I.e. for any element with ID beginning with 'somelist'. When scope is not specified, a global handler is registered, that reacts to an event in any form/widget. |
handler | yes | A javascript handler function that takes two parameters
- the event object and the element id for which the event was
fired. Example:
|
keyCode | no | Keycode to which the event must be triggered. 13 means enter. Either keyCode or key must be specified, but not both. |
key | no | Key, to which the event must be triggered. Key is specified as a certain 'alias'. The alias may be an ASCII character or a digit (this will denote the corresponding key on a US keyboard), a space (' '), or one of the following: 'return', 'escape', 'backspace', 'tab', 'shift', 'control', 'space', 'f1', 'f2', ..., 'f12'. |
keyCombo | no | Key combination, which should trigger the event. It can is specified with key aliases separated with "+" signs. For example "ctrl+alt+f1", "alt+r" etc. |
Registers a 'server-side' keyboard handler that sends an event to the specified widget.
Attribute | Required | Description |
---|---|---|
scope | no | Section 4.3.4, “<ui:keyboardHandler>” |
widgetId | no | Id of Widget that is target of event produced by keyboard handler. |
eventId | no | Id of event that should be sent to target widget. |
eventParam | no | Event parameters |
updateRegions | no | Enumerates the regions of markup to be updated in this widget scope. Please see <ui:updateRegion> for details. |
globalUpdateRegions | no | Enumerates the regions of markup to be updated globally. Please see <ui:updateRegion> for details. |
keyCode | no | Keycode to which the event must be triggered. 13 means enter. Either keyCode or key must be specified, but not both. |
key | no | Key, to which the event must be triggered. Key is specified as a certain 'alias'. The alias may be an ASCII character or a digit (this will denote the corresponding key on a US keyboard), a space (' '), or one of the following: 'return', 'escape', 'backspace', 'tab', 'shift', 'control', 'space', 'f1', 'f2', ..., 'f12'. |
keyCombo | no | Key combination, which should trigger the event. It can is specified with key aliases separated with "+" signs. For example "ctrl+alt+f1", "alt+r" etc. |
This tag should generally be the root of every widget JSP. It makes the widget view model accessible as an EL variable. It can also be used to render a descendant widget in the same JSP with the current widget. In the latter case you should set the id attribute to the identifier path of the descendant widget in question. Note that all widget-related tags inside of this tag will assume that the widget in question is their parent or ancestor (that is all the identifier paths will start from it).
Attribute | Required | Description |
---|---|---|
id | no | A dot-separated widget identifier path leading from the current context widget to the new one. |
Variable | Description |
---|---|
widget | The context widget instance. Can be used to access
JavaBean property data from the widget (e.g.
${widget.foo} will translate to a
getFoo() widget call}. |
widgetId | The full dot-separated identifier of the context widget. |
viewData | The view data of the context widget (see
BaseApplicationWidget.putViewData() ). |
viewModel | The view model of the context widget. |
scopedWidgetId | The scoped id of the context widget. |
<?xml version="1.0" encoding="UTF-8"?>
...
<ui:widgetContext>
...
<c:out value="${viewData.myMessage}"/>
...
</ui:widgetContext>
...
The other use case is to render a descendant widget:
<?xml version="1.0" encoding="UTF-8"?>
...
<ui:widgetContext>
...
<ui:widgetContext id="child.ofMyChild">
<c:out value="${viewData.messageFromChildOfMyChild}"
</ui:widgetContext>
...
</ui:widgetContext>
...
This tag is used when one needs to render a child or descendant
widget while still retaining in both current widget context and JSP. It
publishes the widget view model and full identifier as EL variables, but
does little else and does not setup a widget context (e.g.
<ui:widgetInclude>
tag will not take it into
account).
Attribute | Required | Description |
---|---|---|
id | yes | A dot-separated widget identifier path leading from the current context widget to the target widget. |
Variable | Description |
---|---|
widget | The widget instance. Can be used to access JavaBean
property data from the widget (e.g.
${widget.foo} will translate to a
getFoo() widget call}. |
widgetId | The full dot-separated identifier of the widget. |
viewData | The view data of the widget (see
BaseApplicationWidget.putViewData() ). |
viewModel | The view model of the widget. |
scopedWidgetId | The scoped id of the context widget. |
This tag is used to render some child or descendant widget. It
will call the widget's render()
method, which will
allow the target widget to choose how to render itself.
Attribute | Required | Description |
---|---|---|
id | yes | A dot-separated widget identifier path leading from the current context widget to the target widget. |
path | no | Path to JSP, relative to jspPath of StandardJspFilterService . |
These tags will render a button (or a link) that when clicked will
send a specified event to the target widget with an optional
String
parameter.
Attribute | Required | Description |
---|---|---|
id | no | HTML "id" of the element that can be used to access it via DOM. |
labelId | no | The key of the localizable label that will be displayed on the button. |
eventId | no | The identifier of the event that will be sent to the target widget. |
eventParam | no | String event parameter that will
accompany the event. |
eventTarget | no | ID of receiving widget. Almost never set directly. Defaults to current context widget. |
disabled | no | If set to a not null value will show the button disabled. |
renderMode | no | Allowed values are (button | input) - the corresponding HTML tag will be used for rendering. Default is button.
This attribute only applies to <ui:eventButton> , <ui:eventLinkButton>
is always rendered with HTML link.
|
styleClass | no | The CSS class that will override the default one. |
updateRegions | no | Comma separated list of update regions that should be updated upon button receiving event. This attribute is only needed when using AJAX features—ordinary HTTP requests always update whole page. |
globalUpdateRegions | no | Comma separated list of global update regions that should be updated upon button receiving event. This attribute is only needed when using AJAX features—ordinary HTTP requests always update whole page. |
onClickPrecondition | no | Precondition for deciding whether onclick event should
go server side or not. If left unspecified, this is considered
to be true . |
tabindex | no | This attribute specifies the position of the current element in the tabbing order for the current document. This value must be a number between 0 and 32767. |
The eventButton
tag writes out an HTML
<button>
closed tag with a default CSS class
of "aranea-button".
The eventLinkButton
tag writes out an HTML
<a>
open tag with a default CSS class of
"aranea-link-button".
This tag will register events that are executed when HTML page body has completely loaded. This tag can be used multiple times, all specified events will be added to event queue and executed in order of addition.
This tag checks presence of server-side session-threads that
represent popups and adds system loadevent for opening them in new
browser window at client-side. For tag to have an effect, HTML page
BODY
tag must have attribute onload event set to
AraneaPage (See Aranea Clientside Javascript) onload event. Also, this tag only
works inside <ui:systemForm> tag.
HTML entities can be inserted by using the predefined entity tags or using the <ui:entity> for entities that have not been defined by Aranea JSP library.
The entity
tag accepts a attribute
code
which is used as &code
; to
get the HTML entity.
Attribute | Required | Description |
---|---|---|
code | no | HTML entity code, e.g. nbsp or #012. |
count | no | Number of times to repeat the entity. |
The following predefined entities also accept the
count
attribute. It defines the number of times to
repeat the entity.
Tag | Description |
---|---|
<ui:acute> | HTML ´ entity. |
<ui:copyright> | HTML ©right; entity. |
<ui:gt> | HTML > entity. |
<ui:laquo> | HTML « entity. |
<ui:lt> | HTML < entity. |
<ui:nbsp> | HTML entity. |
<ui:raquo> | HTML » entity. |
<ui:acute> | HTML ´ entity. |
Now we have defined enough JSP tags to render our example widget (see Section 2.7.8, “Putting It All Together”):
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:ui="http://araneaframework.org/tag-library/standard" version="1.2">
<ui:widgetContext>
<h3>Test widget</h3>
Data field: <c:out value="${viewData.myData.field}"/>
<ui:eventButton labelId="#Test" eventId="test"/>
</ui:widgetContext>
</jsp:root>
We can use just usual JSTL Core library
tags to access the widget view data, as long as the
<ui:widgetContext>
is present via the
viewData
EL variable.
Represents a layout. Layouts allow to describe the way content will be placed on the page.
Attribute | Required | Applicable to: |
---|---|---|
width | no | Layout width. |
rowClasses | no | Default style of rows in this layout. |
cellClasses | no | Default style of cells in this layout. |
styleClass | no | CSS class for tag. |
Represents a row in layout.
Attribute | Required | Applicable to: |
---|---|---|
height | no | Row height. |
cellClasses | no | Default style of cells in this row.. |
styleClass | no | Cell css class, defines the way the cell will be rendered. |
overrideLayout | no | Boolean that determines whether row's own styleClass completely overrides styleClass provided by surrounding layout (default behaviour), or is appended to layout's styleClass. |
Represents a cell in layout.
Attribute | Required | Applicable to: |
---|---|---|
height | no | Row height. |
width | no | Row width. |
colSpan | no | Cell colspan, same as in HTML. |
rowSpan | no | Cell rowspan, same as in HTML. |
styleClass | no | Cell css class, defines the way the cell will be rendered. |
overrideLayout | no | Boolean that determines whether cells's own styleClass completely overrides styleClass provided by surrounding layout or row (default behaviour), or is appended to layout's or row's styleClass. |
These two tags define the update regions in the output that can be
updated via AJAX requests. The update regions chosen to be updated when
some event occurs is decided by tags that take the
updateRegion
attribute (See Section 5.2.1, “Common attributes for all form element rendering tags.”).
The <ui:updateRegion>
should be used when
defining updateregion when the region is not contained in HTML table
(layout). The <ui:updateRegionRows>
is for
defining a region which is contained in HTML table and contains table
rows itself. Updating just cells is not possible.
Attribute | Required | Description |
---|---|---|
id | no | The id of the region. Will be used to reference the region when POST'ing a form. |
globalId | no | When not using the globalId , the
full id will be formed by concatenating the context widget id
with the specified id . If for a reason you
would want to avoid that, then you specify the id with the
globalId attribute. |
Either id
or globalId
attribute is required.
<?xml version="1.0" encoding="UTF-8"?>
<!-- First update region, placed outside HTML table -->
<ui:updateRegion id="outsideTable">
</ui:updateRegion>
<ui:layout>
<!-- Second update region, placed inside HTML table -->
<ui:updateRegionRows id="insideTable"/>
<ui:row>
...
</ui:row>
</ui:updateRegionRows>
</ui:layout>
<!-- Button that makes a background submit of specified event.
When response arrives specified updateregions are updated -->
<ui:eventButton id="test" updateRegions="outsideTable,insideTable"/>
Acts as <font> HTML tag.
Attribute | Required | Applicable to: |
---|---|---|
face | no | The font face of the font. |
color | no | The color of the font. |
Sets a CSS class for the tag content, acts as a <span> HTML tag with the class atribute set.
Attribute | Required | Applicable to: |
---|---|---|
styleClass | no | CSS class for tag. |
Defines tooltip that is shown when web application user hovers mouse over element to which the tooltip is attached.
Attribute | Required | Applicable to: |
---|---|---|
element | yes | HTML id of DOM element that is target of the tooltip. |
text | yes | Tooltip content. |
options | no | Options for tooltip (including tooltip classname, title, etc -- see prototip.js for details). |
Represents an HTML form button.
Attribute | Required | Applicable to: |
---|---|---|
renderMode | no | Allowed values are (button | input) - the corresponding HTML tag will be used for rendering. Default is button. |
id | no | Button id, allows to access button from JavaScript. |
labelId | no | Id of button label. |
onclick | no | onClick Javascript action. |
styleClass | no | CSS class for button. |
style | no | Inline CSS style for button. |
Represents a link with an onClick JavaScript action.
Attribute | Required | Applicable to: |
---|---|---|
id | no | Button id, allows to access button from JavaScript. |
styleClass | no | CSS class for tag. |
style | no | Inline CSS style for tag. |
onclick | no | onClick Javascript action. |
labelId | no | Id of button label. |
Usual HTML link, acts as a <a> HTML tag.
Attribute | Required | Applicable to: |
---|---|---|
disabledStyleClass | no | CSS class for disabled link. |
id | no | Link id, allows to access link from JavaScript. |
href | no | Link target URL. |
target | no | Link target, same as <a> HTML tag target attribute. |
disabled | no | Controls whether the link is disabled, disabled link doesn't link anywhere. |
styleClass | no | CSS class for tag. |
style | no | Inline CSS style for tag. |
Aranea standard tag library should mostly be enough to shelter end-users from the need to write HTML inside JSPs. Snippets of HTML are alright but using it too often tends to lead to inflexible UI; instead of embedding HTML in JSPs custom tags should be written if the need arises.
When writing JSPs without embedded HTML, programmers best friends are styleClass attributes of presentation tags, allowing tuning of tag appearances and layout tags.
Layout tags are tags extending BaseLayoutTag
.
Layout tags allow placing of rows inside them (and rows allow using of
cells inside). Standard layout tag (<ui:layout>) outputs HTML
table, and standard row and cell tags output HTML
tr and td tags, respectively.
This is by no means a requirement for layout tags—there are probably ways
to achieve the same behaviour with correctly styled HTML
div tags; but the tables should do just fine for
majority of needs.
Presentation tags (tags extending PresentationTag
or implementing StyledTagInterface
) have attribute
styleClass
that specifies the CSS style class used for
rendering the tag. When styleClass
attribute for tag is
not specified, some default style bundled with Aranea is used; or in some
cases no HTML class
attribute is output at all—allowing
cascading styles from some parent (HTML) tag to take over the
presentation.
Presentation tags also have style
attribute for
specifying inline style for tag. Using it is discouraged—tweaking style
classes to fit ones specific needs is highly recommended.
Some tags may have more than one attributes for defining tag style.
For example <ui:layout>
tag and other layout tags
that extend LayoutHtmlTag
or
BaseLayoutTag
have attributes
rowClasses
and cellClasses
that
specify the default styles for <ui:row>
and
<ui:cell>
tags used within the layout. These can
be overriden with row and cell own styleClass
attribute.
To actually use new style(s) for some tag one often can just write a
new CSS style (i.e. "somestyle { background: #ffc; color: #900;
text-decoration: none; }"
)—apply that and be done with it. For
more complicated tags, one may need to take a quick peek at tag source
code to see what HTML tags are output and design their styles accordingly.
Most of the time that should not be necessary.
Changing default tag styles can be done in two ways—modifying CSS files or extending the tag one wants to customize with dynamic initializer like this:
{
styleClass = "some-wanted-style";
}
needless to say, first method is very much preferred because creating custom tags just for changing tag styles is quite pointless.
There is also a renderMode
attribute; in current
tag library there are very few tags supporting this attribute. One of
those is ButtonHtmlTag
(<ui:basicButton>
)—its renderMode should have
value "input"
or "button"
(default)
and it specifies whether the button should be rendered in HTML with
<input type=button ... >
or <button
... >
tag. In the future, number of JSP tags having
renderMode attribute will probably increase (this can be used to get rid
of multiple JSP tags for rendering different types of (multi)selects,
inputs and displays).
Attribute | Required | Applicable to: |
---|---|---|
style | Inline CSS style applied to tag. Avoid. | Presentation tags. |
styleClass | CSS class applied to tag. | Presentation tags. |
rowClass | CSS class applied to rows inside the tag. | Layout tags. |
cellClass | CSS class applied to cells inside the tag. | Layout tags, row tags. |
renderMode | Defines the renderMode used for rendering the tag. | <ui:basicButton> ,
<ui:eventButton> ,
<ui:button> . |
Custom tags should extend at least org.araneaframework.jsp.tag.BaseTag that provides methods for registering subtags, manipulation of pagecontext and attribute evaluation.
import java.io.Writer;
import org.araneaframework.jsp.tag.entity.NbspEntityHtmlTag;
import org.araneaframework.jsp.util.JspUtil;
public class DummyTag extends BaseTag {
public static String KEY = "org.araneaframework.jsp.tag.DummyTag";
BaseTag subTag;
@Override
protected int doStartTag(Writer out) throws Exception {
int result = super.doStartTag(out);
// make this tag implementation accessible to subtags which
// is quite pointless since this tag does not implement any useful interface.
// it demonstrates Aranea JSP convention for providing info to subtags
addContextEntry(KEY, this);
// write some real output that ends up at the served web page
JspUtil.writeOpenStartTag(out, "div");
JspUtil.writeAttribute(out, "id", "dummyDivId");
JspUtil.writeCloseStartTag(out);
// it is possible to register in JAVA code too, this one just writes out nbsp entity.
subTag = new NbspEntityHtmlTag();
registerSubtag(subTag);
executeStartSubtag(subTag);
return result;
}
@Override
protected int doEndTag(Writer out) throws Exception {
executeEndTagAndUnregister(subTag);
JspUtil.writeEndTag(out, "div");
return super.doEndTag(out);
// Now everything about this tag ceases to exist,
// context entries are removed, souls are purged.
}
}
org.araneaframework.jsp.util.JspUtil
that was
used here is an utility class containing some functions for writing out
(XML) tags with somewhat less room for errors than just
out.write()
. Other notable methods provided by
BaseTag
are getOutputData()
that
returns response data, getConfiguration()
and
getLocalizationContext()
. For tags with attributes,
attribute evaluation functions that support Expression
Language (EL) expressions are provided in
BaseTag
. Typical usage of these functions is
following:
public void setWidth(String width) throws JspException {
this.width = (String)evaluate("width", width, String.class);
}
Another common base tag for tags that output real HTML is
org.araneaframework.jsp.PresentationTag
. The
DummyTag
should really extend it too, since it
outputs some HTML. PresentationTag
defines
style and styleClass
attributes that can be applied to most HTML tags.
Important tag cleanup method is doFinally()
that is called after rendering. It should be used to clear references to
objects that should no longer be referenced after rendering. As in
containers tag instances can live very long time, they can leak quite a
lot of memory unless resources are deallocated.
Custom tags extending Aranea tags are able to accept all supertag attributes,
but these must be also defined in TLD, otherwise the JSP containers
will complain. As some base tags may be abstract, information about
their attributes cannot be deduced from Aranea JSP standard TLD.
To address this problem, Aranea distribution does the following:
aranea.jar and aranea-jsp.jar include the file META-INF/aranea-standard.tcd
(TCD stands for Tag Class Descriptor)
which includes the attribute information for all Aranea Standard JSP classes.
To make use of this information, one first generates TLD for custom tag classes and then
merges the TCD information into it. It is done with org.araneaframework.buildutil.TcdAndTldMerger
utility included in aranea.jar (since 1.0.10, previously it had to be compiled separately after downloading distribution).
All custom compiled tag classes as well as Aranea JSP tag classes must be available on classpath when using this utility.
Example of using the TcdAndTldMerger
utility:
<target name="tld">
<!-- generate TLD without parent attribute information -->
<webdoclet destdir="somedir" force="false" >
<fileset dir="${src.dir}" includes="**/*Tag.java"/>
<jsptaglib validatexml="true"
shortName="shortName"
filename="filename.tld"
uri="customuri"
description="description"
/>
</webdoclet>
<!-- invoke the TcdAndTldMerger utility -->
<java classname="org.araneaframework.buildutil.TcdAndTldMerger" fork="true">
<arg value="META-INF/aranea-standard.tcd"/> <!-- Tag class descriptor to merge with -->
<arg value="somedir/filename.tld"/> <!-- Source TLD -->
<arg value="somedir/filename.tld"/> <!-- Destination TLD -->
<classpath>
<path refid="araneaclasspath"/>
<path refid="compiledcustomtagclasses"/>
<path refid="varia">
</classpath>
</java>
</target>
When running given target, one should see messages similar to following:
8 attributes for 'custom.RandomTag' found from 'org.araneaframework.jsp.tag.presentation.PresentationTag'.
Sending events to widgets is accomplished with javascript submit
functions, helpful utility being
org.araneaframework.jsp.util.JspUtil
and
org.araneaframework.jsp.util.JspWidgetCallUtil
. First
one would construct org.araneaframework.jsp.UiEvent
and (in case of HTML element which receives only one event) calls
JspUtil.writeEventAttributes(Writer out, UiEvent
event)
and afterwards
writeSubmitScriptForEvent(Writer out, String
attributeName)
.
//public UiEvent(String eventId, String eventTargetWidget, String eventParameter)
UiEvent event = new UiEvent("hello", "contextWidgetId", "name");
// long way to ouput custom attributes version
JspUtil.writeEventAttributes(out, event);
JspWidgetCallUtil.writeSubmitScriptForEvent(out, attributeName);
// short version
JspWidgetCallUtil.writeSubmitScriptForEvent(out, "onclick", event);
// both will output something like this:
// arn-evntId="hello"
// arn-trgtwdgt="contextWidgetId"
// arn-evntPar="name"
// onclick="return _ap.event(this);"
New layouts are mostly concerned with styles or render layouts
with some additional tags instead plain table, tr,
td
. As simple example, we define a layout that applies a class
"error" to cells which contain invalid FormElement
.
Note that approach we use only works when cell tag is aware of the
surrounding FormElement
at the moment of rendering,
meaning that FormElement
is rendered in JSP something
like this:
<?xml version="1.0" encoding="UTF-8"?>
...
<ui:formElement id="someId">
<ui:cell>
<ui:label/>
</ui:cell>
<ui:cell>
<ui:textInput/>
</ui:cell>
</ui:formElement>
...
What is needed foremost is a decorator for cells that are used
inside invalid FormElement
.
public class ErrorMarkingCellClassProviderDecorator implements CellClassProvider {
protected CellClassProvider superProvider;
protected PageContext pageContext;
// constructs a decorator for superProvider, makes pageContext accessible
public ErrorMarkingCellClassProviderDecorator(CellClassProvider superProvider, PageContext pageContext) {
this.superProvider = superProvider;
this.pageContext = pageContext;
}
public String getCellClass() throws JspException {
FormElement.ViewModel formElementViewModel = (FormElement.ViewModel)
pageContext.getAttribute(FormElementTag.VIEW_MODEL_KEY, PageContext.REQUEST_SCOPE);
// superProvider.getCellClass() may only be called once, otherwise moves on to next cell's style
String superClass = superProvider.getCellClass();
if (formElementViewModel != null && !formElementViewModel.isValid()) {
if (superClass != null)
return superClass + " error";
else
return "error";
}
return superClass;
}
}
Actual layout tag that decorates its cells according to described logic:
public class CustomLayoutTag extends LayoutHtmlTag {
protected int doStartTag(Writer out) throws Exception {
int result = super.doStartTag(out);
addContextEntry(CellClassProvider.KEY, new ErrorMarkingCellClassProviderDecorator(this, pageContext));
return result;
}
}