Vita Rara: A Life Uncommon

Creating a Theme in Struts 2


Categories: |

Struts 2 has a very powerful set of user interface tags (UI Tags). These tags are tightly integrated with the framework, taking full advantage of things like the OGNL Value Stack. The power this gives to a user it tremendous.

Struts 2 UI Tags

The Struts 2 UI Tags are backed with templates that do the actual rendering of HTML. You can change them without any need to touch the implementing classes. As of Struts 2.0.2 these templates are written in the FreeMarker template language. A quick look at the Freemarker Manual will provide you a quick overview of the language, and is helpful if you have questions about the language. Anyone familiar with JSP, PHP, or other template languages can quickly grasp it.

The Sample Application

Download the sample application, linked below. This is a Maven 2 project. To build the application run: "mvn package". This will create a war file in the target directory called: struts2themes.war. Deploy this war file to your Servlet container, such as Tomcat.

The XHTML Theme

Struts 2 ships with several themes, including a simple one that simply outputs the html form tags. The theme we are going to start with is the XHTML theme. This theme is designed to output valid XHTML markup, and by default lays forms out in a two column table with the label for each input field in the left column and the input field in the right column. This will get us started.

To see the layout created by this theme click the "Standard XHTML Form" button in the sample application.

This JSP markup to create this form is quite simple, and is a testament to the power of the Struts 2 UI Tags:


<s:form action="some.action" method="post" theme="%{currentTheme}">
    <s:textfield label="First Name" name="firstName"/>
    <s:textfield label="Last Name" name="lastName"/>

    <s:textfield label="Address 1" name="address1"/>
    <s:textfield label="City" name="city"/>

    <s:textfield label="State" name="state"/>
    <s:textfield label="Zip" name="postalCode"/>

    <s:submit value="Create Party" align="center">
        <s:param name="colspan" value="%{tableColSpan}" />
        <s:param name="align" value="%{'center'}" />
    </s:submit>
</s:form>

As you can see the template contains no HTML markup at all. All of the layout is done by the tags, and the templates that back them. Using these tags you can save an enormous amount of time writing table, tr and td tags.

The issue though is that many web applications contain forms that are far more complicated than are accommodated using a two column layout. Sometimes we need to do column spans, row spans, and use more then two columns.

Sometimes we need a form that looks like this:

This is an eight (8) column layout from a project I'm currently working on called Quadran. An excerpt from the JSP source code:

<s:textfield label="Requested Delivery Date" name="order.dutyPrepaid"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{2}" /> 
</s:textfield>
<s:textfield label="Third Party Bill To" name="order.dutyPrepaid"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{2}" /> 
</s:textfield>
    
<s:textfield label="Trucker" name="order.dutyPrepaid" size="70"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{6}" /> 
</s:textfield>
    
<s:textfield label="Loading Instructions" name="order.dutyPrepaid" size="70"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{6}" /> 
</s:textfield>
    
<s:textfield label="Shipping Instructions" name="order.dutyPrepaid" size="70"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{6}" /> 
</s:textfield>

S2 Tags Overview

The Struts tags are a powerful set of tags usable in JSP, FreeMarker and Velocity. They are completely integrated into the Struts 2 framework, taking advantage of the ValueStack and the OGNL expression language. Additionally the UI tags are backed by template. This allows the markup they generate to be changed without resorting to editing the Java source files. It's as easy as including your template files on your classpath.

Let's start with a simple example. We will examine the template that backs the <s:textfield> tag from the simple theme. (This file can be found in core/src/main/resources/template/simple in the Struts 2 source.)


<input type="text"<#rt/>
 name="${parameters.name?default("")?html}"<#rt/>
<#if parameters.get("size")?exists>
 size="${parameters.get("size")?html}"<#rt/>
</#if>
<#if parameters.maxlength?exists>
 maxlength="${parameters.maxlength?html}"<#rt/>
</#if>
<#if parameters.nameValue?exists>
 value="<@s.property value="parameters.nameValue"/>"<#rt/>
</#if>
<#if parameters.disabled?default(false)>
 disabled="disabled"<#rt/>
</#if>
<#if parameters.readonly?default(false)>
 readonly="readonly"<#rt/>
</#if>
<#if parameters.tabindex?exists>
 tabindex="${parameters.tabindex?html}"<#rt/>
</#if>
<#if parameters.id?exists>
 id="${parameters.id?html}"<#rt/>
</#if>
<#if parameters.cssClass?exists>
 class="${parameters.cssClass?html}"<#rt/>
</#if>
<#if parameters.cssStyle?exists>
 style="${parameters.cssStyle?html}"<#rt/>
</#if>
<#if parameters.title?exists>
 title="${parameters.title?html}"<#rt/>
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
<#include "/${parameters.templateDir}/simple/common-attributes.ftl" />
/>

This template is written in FreeMarker. It starts by emitting the beginning of an input tag of type text on the first line. Then using #if statements it examines the various possible parameters to the tag and outputs the appropriate HTML. Near the bottom it includes two additional scripts: scripting-events.ftl and common-attributes.ftl for handling scripting and attributes that are common to all HTML tags.

This method of building scripts by including others is used pervasively throughout the templates.

The parameters that are passed into the tag via attributes are available using the parameters object. We will use this object to access additional parameters to extend the XHTML theme.

Our New Theme

The goal of our new theme is to extend the XHTML theme to support layout of forms using an arbitrary number of columns. The default XHTML theme only support a two column layout, with labels on the left and inputs on the right, each in their own <td>.

Our theme will have the following attributes:

  • Allow for an arbitrary number of columns in the table containing our form,
  • Require no use of HTML markup,
  • Allow for arbitrary display of data integrated into our theme that isn't an HTML input,
  • Allow the number of columns to be specified for the label, and the input independently,
  • Inputs will not require a label, and if none is present no table elements will be emitted for the label.

The qTableLayout Bean

To specify the configuration of our table layout for our form we need to create a bean prior to the opening <s:form> tag. I have experimented to no avail using the <s:param> tag to parameterize the <s:form>, but have not succeeded. To work around this we simple create a bean holding our table configuration before we start our form.


<s:bean name="java.util.HashMap" id="qTableLayout">
    <s:param name="tablecolspan" value="%{4}" />
</s:bean>

The qTableLayout is a HashMap and holds one property, tablecolspan, which is the number of columns we want our form to use. The sample above would produce a layout using four columns.

Accessing the qTableLayout Bean in FreeMarker

One of the keys to making our theme work is being able to access the qTableLayout bean in our FreeMarker templates, change values contained in it, using it as a means of passing information between our tags. We use it to maintain the state of our table. Particularly the number of columns we have emitted for the current row.

To update the qTableLayout bean we use the following in the FreeMarker template:

${stack.setValue('#qTableLayout.currentColumnCount', columnCount)}

This statement accesses the OGNL ValueStack and stores the currentColumnCount in our qTableLayout bean. This allows our theme to maintain state between each invocation of the FreeMarker templates that back the Struts 2 tags.

Table Layout Logic

When creating a new theme it's usually better to start with an existing theme and extend it. For our example we will start with the XHTML theme. To start the new theme you would make a template directory in your WEB-INF/classes directory, then in that one make a directory with the same name as your theme, in our case "qxhtml". Then copy all of the files from the XHTML theme in the Struts 2 distribution into qxhtml to form the basis of our new theme. (NB: You don't need to do all of this. It's already done in the sample app.)

With all of our templates in our directory it's time to start hacking. We need to control the emitting of the <tr> tags. These are emitted by default in the XHMTL theme. The first thing we need to do is remove these from the XHTML template. These statements are in the controlheader-core.ftl and controlfooter.ftl templates in the XHTML theme. In qxhtml these have been removed and two new files have been introduced: controlheader-trlogic.ftl and controlfooter-trlogic.ftl.


<#--
    	controlheader-trlogic.ftl

	This template handles:
        * intializing qTable.currentColumnCount if it has not been initialzed,
        * emiting a <tr> tag if the currentColumnCount == 0,
-->
<#if qTableLayout.exists && ! qTableLayout.currentColumnCount?exists >
    <#-- Set the currentColumnCount to 0 because this is the first row of the table. -->
    ${stack.setValue('#qTableLayout.currentColumnCount', 0)}
</#if>
<#-- Do we need to write the opening tr tag. -->
<#if qTableLayout?exists && qTableLayout.tablecolspan?exists >
    <#assign columnCount = qTableLayout.currentColumnCount />
<#else>
    <#-- Set the currentColumnCount to 0 because this is the first row of the table. -->
    ${stack.setValue('#qTableLayout.currentColumnCount', 0)}
    <#assign columnCount = 0 />
</#if>
<#if columnCount == 0>
    <#-- Write out the opening tr tag to start the table row. -->
    <tr><#rt/>
</#if>

As you can see in this listing the qTableLayout bean is used to hold the currentColumnCount, which is used to if we need to emit a <tr> tag when the column count equals zero (0). In the controlfooter-trlogic.ftl template if the current column count is equal to or greater than the qTableLayout.tablecolspan the template will emit our closing <tr> tag.

Using Our New Theme

The qxhtml theme supports more than just doing a multi-column layout. It also supports specifying the number of columns you would like the label and the input to be using <s:param> tags. Here's a quick snippet from our complex example above:


<s:textfield label="Loading Instructions" name="order.dutyPrepaid" size="70"> 
    <s:param name="labelcolspan" value="%{2}" /> 
    <s:param name="inputcolspan" value="%{6}" /> 
</s:textfield>


Inside our <s:textfield> tag we have nested two <s:param> tags, one to specify the number of columns for our label, and the input. This allows us great flexibility in laying out our forms.

Out theme also supports simply out putting an input without a label. Just omit the label from your tag:

<s:textfield name="someProperty" />>

This will emit a <td> containing an HTML input only. No label will be generated. This allows you to do tabular inputs very simply as follows:

<s:textfield name="propertyOne" />>
<s:textfield name="propertyTwo" />>
<s:textfield name="propertyThree" />>
<s:textfield name="propertyFour" />>

If you configured your form to have four (4) columns this would result in one row. Wrap this in an <s:iterator> tag and you can quickly create tabular input screens for updating large numbers of records.

The Sample App

The sample application contains one form in form.jsp. Deploy the application and view it. If you've deployed this on your local machine using Tomcat you can go to: http://localhost:8080/struts2themes/. Click the "Standard XHTML Form," "Four Column," and "Six Column" buttons to view the form in two, four and six column layout. Each of these layouts is produced from the exact same markup. The only difference is the a property of the action that sets the number of columns to use.

To see a complex form click "Complex Form" in the navigation. This is a subset of the complex form in the screen shot above. The source for the form is:


<%-- Setup the number of columns to be in the table layout for the form. --%>
<s:bean name="java.util.HashMap" id="qTableLayout">
    <s:param name="tablecolspan" value="%{8}" />
</s:bean>
<s:form action="complexForm.action" method="post" theme="qxhtml">
    <s:textfield label="SO Number" name="order.fromPartyOrderNumber"> 
        <s:param name="labelcolspan" value="%{2}" /> 
        <s:param name="inputcolspan" value="%{2}" /> 
    </s:textfield>
    <s:select name="salespersonId" label="Salesperson" list="genericList" listKey="id" listValue="name"> 
        <s:param name="labelcolspan" value="%{2}" /> 
        <s:param name="inputcolspan" value="%{2}" /> 
    </s:select>

    <s:textfield label="Trucker" name="order.dutyPrepaid" size="70"> 
        <s:param name="labelcolspan" value="%{2}" /> 
        <s:param name="inputcolspan" value="%{6}" /> 
    </s:textfield>

    <s:select name="newPoRequired" label="New PO Required" list="genericList"
               listKey="id" listValue="name" />
    <s:select name="shipdateConfirmed" label="Ship Date Confirmed" 
               list="genericList" listKey="id" listValue="name" />
    <s:select name="accounting90EntryDone" label="Acctg Entry Done" 
               list="genericList" listKey="id" listValue="name" />
    <s:select name="factored" label="Factored" list="genericList" listKey="id" 
               listValue="name" />

    <tr><th align="center" colspan="8">Line Items</th></tr>

    <tr>
        <th>#</th>
        <th>Product</th>
        <th>Qty</th>
        <th>Unit Price</th>
        <th>Allocation Instructions</th>
        <th>Label Instructions</th>
        <th>Description</th>
        <th>Override Reason</th>
    </tr>

    <s:iterator value="lineItems" status="status">
        <s:component template="/components/textcell.ftl" value="%{#status.index}" />
        <s:select name="termsId" list="genericList" listKey="id" listValue="name" />
        <s:textfield name="test" size="1"/>
        <s:textfield name="test" size="1"/>
        <s:textfield name="test" size="1"/>
        <s:textfield name="test" size="1"/>
        <s:textfield name="test" size="1"/>
        <s:textfield name="test" size="1"/>
    </s:iterator>

    <s:submit value="Create Sales Order" align="center">
        <s:param name="colspan" value="%{8}" />
        <s:param name="align" value="%{'center'}" />
    </s:submit>
</s:form>

This sample shows the full power of the theme at this point. It uses variable label and input column spans, textfield without labels, and a custom component for outputting text in a table data, but including it in the theme and counting columns so the table rows are started appropriately. (Look at the first tag inside the iterator for the component.)

Here's what it looks like:

Future Improvements

This theme is very usable in its current form. There are some things I'd like to add. The most important of these is row spanning. I have some ideas on how to do it, but haven't tackled it. Other improvements could be had with a minor change to the existing Struts 2 tags, but that involved actually digging into the class files, and I'm not ready for that yet. To be honest I've never written a JSP tag. I have asked for some pointers on the Struts users list though. So, we'll see.

AttachmentSize
struts2themes.tar_.gz18.53 KB

How to rowspan

Hi, great post. It help me a lot of.

But I need use rowspan when i use a textarea in a form. I try to modif the qxhtml theme for these purpose but i is not a expert in freemarket.

Can anybody help me?

One row multiple fields

Hi

I could not able to place two text fields in single row. Do you have any solution for this? I mean a theme, which has all the functionalities of struts but it does allow the multiple fields in the same row?
By the way when we use the and to align the fields, the filed error is repeated as many number of time as you submit the form.
If you have a solution for this, please save me form inventing the wheel again.
Regards
Raj

labelposition

Hi, thanks a lot for this great tutorial it´s been very helpful.

I cannot make the labelposition attribute of the textfield to work using the qxhtml template. Does any one know if there's a solution for this?

Thanks in advance
Gaston

Solved - Colspan not working for some "input" tags like "submit"

Great Work ! So while I am happy I like to give here some hints...

I noticed that in my struts version 2.1.6 for instance the "colspan" for the "<s:submit>" was not working. The reason is the same as Mark noticed that simple "parameters" are not passed. So how to pass the parameters to your UI tag?

Well the "<s:submit>" and also the "<s:form>" tag are "open-" and "closing-tags".

public abstract class FormButton extends ClosingUIBean
public class Form extends ClosingUIBean

The passing of the parameters happens not during the "open-tag", it happens at the "closing-tag". The content resp. the body and its child tags (param tags) are getting later evaluated and are available when thhe "closing-tag" is executed.

// e.g. the "end" tag evaluation of the "parameter tag"
// initializes its owner with the parameters
public boolean end(Writer writer, String body) {
Component component = findAncestor(Component.class);
....
component.addParameter(name, value);
}

These "open-" and "closing-tags" have also 2 freemarker templates. e.g. an "open" which is for instance the "submit.ftl" and the "submit-close.ftl"

In the example, you provided only an "opening" template. So in case you test there for instance for parameters then you will get nothing.

So to solve my problem for the provided example. Rename the provided "submit.ftl" to "submit-close.ftl" and empty the "submit.ftl"

With some refactoring you should also now be able to get rid of the "qTableLayout" and use instead "s:param" tags.

regards
Mark Egloff

I see great value in

I see great value in creating themes for language-specific websites. A template could handle arabic that is read from right to left. Moreover switching themes is also easy like a portal switching look-and-feel.

Mohan

Overriding the validation.js

Nice tutorial. How do you override the validation.js file? I have change the paths to look at my own validation.js under my theme and it always uses the validation.js in the struts 2 jar file. Any help would be appreciated.

Override FORM tag for using custom validation

If you are using the "simple" theme, you should override templates form.ftl and form-close.ftl, otherwise you should change a name of JavaScript in form-validate.ftl (override the template)

Alex C

Nice work

Nice work Mark!

Article is very much useful.

Keep it up.

Regards,

Jamy.

custom table

hi,
plzz help me out... we have design framework in struts2 and currently working on jsp pages.... so how we will implement this theme (full code) in our application..... plz help me... reply.......

please help me urgent

I am a newbie to struts 2 and freemarker. This article is helpful but i am not happy. I did as what u told here like a walkthrough but it showed me errors related to the file path that i managed and fixed. Please Make this article as a walkthrough(I will help us) and make points clear as much u can.
Now, I can see the table structure as well,
But, the label is not displaying only the textfield is getting displayed for this code.

<s:textfield label="SO Number" name="fromPartyOrderNumber">
<s:param name="labelcolspan" value="%{2}"/>
<s:param name="inputcolspan" value="%{2}" />
</s:textfield">

Another issue,
how can u get the labelcolspan value and inputcolspan value?
how do u get the current no. of tags?
is that controlheader-trlogic.ftl is complete or partial.
controlfooter-trlogic.ftl was not worked i just changed code in controlfooter.ftl to include controlfooter-trlogic.ftl.

Please help me asap.
with regards,
TAK

Validation not working..

Hi Mark,

Thanks for the great article. I used your code and its working great. Client side validation is not working with theme qxhtml is there any reason or am i missing any thing. I am using Struts 2.0.9 and spring. I appreciate your help

Thanks
VK

Validation

I think all of the client side validation is built into the Freemarker templates. I don't think I started from those ones for the theme.

Validation

Hi Mark,

Thanks for your reply,
To get the dropdown values i go to action to open the jsp page using return INPUT this works fine. When I add ActionName-validation.xml its not going to action class and not getting the dropdown values and showing field validation errors.
How to stop the validation at that time. pl help me in solving this problem

Thanks
VK

Having trouble using s:datetimepicker / struts 2.0.11

Great article, I'm almost there, but the datetimepicker widget doesn't seem to render, Im guessing things have changed in 2.0.11. The file template/simple/datepicker.ftl is missing / renamed.

I've tried updating this to 'datetimepicker.ftl' which is in the struts-core jar, and all errors go away, it just doesn't render so I'm a bit lost.

Datetimepicker

Template name change isn't enough. <s:head /> tag must be added to the <head> tag of the JSP page as well:

<head>
<title>Create Sales Order</title>
<s:head theme="ajax" />
</head>

Datetimepicker is shown, but unfortunately its layout is not perfect ... :)

Great tutorial- easy to follow

Nice tutorial. Took less than 2 hours before I had my own theme set up by following the example. I've found that the Struts2 tag/component classes are also very easy to extend if you want to add your own tag attributes. I'm doing a lot of work with Dojo 1.0 attributes which the bundled struts tags do not cover. Extending the existing tag classes is as simple as adding the additional attributes and setter methods.

Dave Shapiro

Struts2 theme

i am using sun application server i want to create my own theme.i have downloaded above example but i don't know how to setup those files.that means where to put qxhtml file ete.. pls help me. thank u

my email is nglasantha@gmail.com

Where to put theme files

The theme files ultimately need to end up on WEB-INF/classes/template//.

Where you would place those in your project file structure I'm not sure. I'm using a Maven based build and place my file under src/main/webapp/WEB-INF/classes/template/qxhtml/.

Take care,

Mark

Trouble building smple using Maven

Nice tutorial!
It solves a lot of formatting issues. It would be great if was part of the STRUTS 2 library itself.

I have trouble getting the war to extract as am new to Maven. Can anyone please provide instructions?

Thanks a bunch!

Feature Improvement - Rows Spanning

Mark,

I am enjoy reading this article, it is very useful. you mentioned that one of new feature that you would like to add is to add Rows Spanning. Would you mind to share your idea how to implement this feature? I am working with a project that will require to display arbitary columns and rows in a single table.

Thanks

Eric

Great Guide!!!

Hello Mark!

Very good guide! Before I begin, this is just sharing my 2 cent opinion and by no means of degrading Struts 2.

I don't know FreeMarker but I understood it since it's very similar to JSTL. Anyways, I just want to comment on Struts 2 theme, not your guide! As of now, I write all JSP pages in plain "html/xhtml" w/ no specification to any css class or styles. I override the default HTML setting in my CSS file, which impacts entire feel and look. So, if I want to change the theme, I just swap single CSS file w/o impacting any of the JSP files. Clearly, this would be very useful to a developer who knows little about CSS. But, for anyone who has used CSS extensively would probably prefer creating the entire theme based on "css" and not through struts tag lib. Of course, you can combine Struts 2 theme + CSS but I don't see any advantage of using Struts 2 theme. So, I'm wondering what would be the advantage of using Struts Theme vs. Pure CSS solution. Again, thanks for the great article and look forward for your reply. Perhaps I'll be conviced to use Struts 2 theme. Thanks.

Struts 2 Theme vs. CSS

Well, the Struts 2 theme really isn't a replacement for CSS, nor is CSS a replacement for the Struts 2 theme.

The Struts 2 theme is a way of customizing the markup emitted from a template engine (JSP). CSS is a way of styling said markup in the rendering engine (the browser).

Basically creating a theme in S2 just allows you to control the markup that is emitted from the S2 tag library. In my case I wanted the standard tags, which by default do a two column tabled layout of form elements, to emit a variable column width tabled layout.

So, in reply I would say that you can't accomplish the real end result without both the S2 theme, and a CSS style sheet, which combined get you to a final appearance, or what most might think of as a theme, in your browser.

Which raises an issue of terms. A S2 theme really isn't about how the markup should be styled, but what markup is going to be generated.

Mark

hey mark can you please help me with the theme you have made?

hey actually what i want is, aligning the value of the label inside the labelspan and am unable to do it using any approach which i tried. Can you please help me in doing that as i don wish to use html tags in my page.Plz reply asap on dhshridhar@yahoo.com or here,
thanks

Very Useful Theme..

Hi Mark, Thanks for sharing this great theme. I am implementing it for my current project. However I have a question.
How should I read lineitems collection values in action?
Do we need to define MyAction-conversion.properties ?
Can you pl. reply me on my mail id techhelp07@gmail.com ?

Thanks in Advance..
Raghu

Basic XHTML mod

Hey, I'm a bit of a newbie when it comes to strut themes. I'm trying to make some basic changes to the xhtml theme. I put the xhtml original directory in my classes directory and it detects it (I think it does at least because it displays as if it were normal xhtml but the theme is set to myxhtml). However I haven't been successful making any changes to it. I tried changing the color of the error, and other text in the css for example and it's made no difference. I also modified the head to :

" type="text/css"/>

I'm stuck though and theres not much about it online. If anyone can help, please email me at booies@aol, or respond here.

using divs in table

first of all, great tutorial and great theme man, works fine

but one question, in my forms i have a combobox, and according to which item selected in the cbox there will be fields shown and not shown, what i wanted to do is for each item selected i create a div which hold the fields for that selected item and i set the display then. But the problem is that the struts forms are tables, the divs are placed between trs and it is not working. I can make it work if use the css_xhtml theme, but then ofcourse the forms aren't layout as proper as this theme. So my question, can i achieve that with your theme or does anyone has extended teh css_xhtml theme to a theme like the qxhtlm theme, i will look myself at the theme, but i am not sure it will work...

thx TOm

Ajax theme

Hi,

Your theme works fine with xhtml tags. But I also have ajax tags in my form like . That forces me to include the ajax theme which doesn't work with the new qxhtml theme and my autocompleter is not displayed at the right place.

So I've tried to create a new qajax theme which references qxhtml template but Freemarker complains I get that error :

Expression ww is undefined on line 1, column 32 in template/qxhtml/head.ftl.
The problematic instruction:
----------
==> user-directive ww.url [on line 1, column 30 in template/qxhtml/head.ftl]
in include "/${parameters.templateDir}/${themeProperties.parent}/head.ftl" [on line 2, column 1 in template/qajax/head.ftl]

line 1 from qxhtml/head.ftl :
<link rel="stylesheet" href="<@ww.url value='/webwork/xhtml/styles.css' encode='false' />" type="text/css"/>

qajax/head.ftl :
<#--include "/${parameters.templateDir}/qxhtml/head.ftl" /-->
<#include "/${parameters.templateDir}/${themeProperties.parent}/head.ftl" />
<script language="JavaScript" type="text/javascript"
src="<@s.url value='/struts/qajax/dojoRequire.js' includeParams='none' encode='false' />"></script>
<script language="JavaScript" type="text/javascript"
src="<@s.url value='/struts/CommonFunctions.js' includeParams='none' encode='false'/>"></script>

How can I fix it ?

Thank you.

I need your qajax theme. Is

I need your qajax theme. Is it available somewhere?

Thank you

How can i access s:url tag in javascript

hi All,

could please tell me how to append parameters to s:url in javascript..

thanks and regards
shrini.

qTableLayout

I extended your usefull template to use a new parameter layout. "lineDirection" is the default value for your solution. When "pageDirection", I create one line tr for label and another for input.
As I was testing I displayed ${parameters} and saw that there was a parameter called "form" which contains each form parameters. So, I could access to my parameter added in the s:form tag by calling ${parameters.form.layout}.
Consequently, you could modify your template so that you could add s:param name="tablecolspan" value="%{2}" in the s:form tag.

Next extension will be to add a new parameter layout to radio and checkboxlist : when "pageDirection", there will be a br after each radio or checkbox
Anne

Error if I do not define the qTableLayout bean

If I have a form where I do not set the qTableLayout bean, I get this error:

Method public void com.opensymphony.xwork2.util.OgnlValueStack.setValue(java.lang.String,java.lang.Object) threw an exception when invoked on com.opensymphony.xwork2.util.OgnlValueStack@1352367
The problematic instruction:
----------
==> ${stack.setValue('#qTableLayout.currentColumnCount', 0)} [on line 15, column 9 in template/qxhtml/controlheader-trlogic.ftl]
in include "/${parameters.templateDir}/qxhtml/controlheader-trlogic.ftl" [on line 1, column 1 in template/qxhtml/submit.ftl]
----------

Java backtrace for programmers:
----------

[ Bunch of stuff removed ]

Caused by: ognl.OgnlException: target is null for setProperty(null, "currentColumnCount", 0)

This happened because I change the default theme in struts and did not update all the forms in the webapp.

Is there a way to tell qxhtml to work like xhtml if qTableLayout is not defined?

Fix for qTableLayout errro

Mark:

I changed controlheader-trlogic.ftl to have this code and it worked:

tag if the currentColumnCount == 0,
-->

${stack.setValue('#qTableLayout.currentColumnCount', 0)}

${stack.setValue('#qTableLayout.currentColumnCount', 0)}

You probably want to update your code with this as well.

Thanks,
Neil

Formatting messed up

Mark:

It looks like your blog did not like the freemarker template code. It probably interpreted it as HTML.

I posted it here:
http://jamm5.jammconsulting.com/controlheader-trlogic.txt

Thanks,
Neil

Different style between label and input text field

Hi Mark,
Thanks for the nice how to.

Anyway, I have a question :)
What if we want to have different style (bgcolor for example), between input text element and its label?

Re: Different style between label and input text field

There is a cssClass argument to the Struts 2 UI components. Looking at the templates this applies to the actual input control. So, short of using an s:param tag there is no easy means of getting a different css class on the TD for the input or label TD's.

With that said, if you want to style all of your forms the same, the label TD does have a class of tdLabel. So you could easily use a style sheet to style that. Also the opening TD tag for the input element in is the controlheader.ftl template. You could add 'class="tdInput"' to that, allowing you to also style it using your css style sheet.

Mark

Re: Different style between label and input text field

Thx Mark...it's not really clean though :(

Actually, first I prefer using simple "plain" theme which is the most flexible. But in simple theme, I lose the client side (pure javascript & ajax) validation. I could write javascript validation manually, but I hate to lose the integrated server and client side validation.

So I think I'm gonna try to write a template that does the 'alert-style' javascript validation, like in the old Struts 1.x.

How do make 2 buttons align within one row?

I find your article very useful in designing forms. However, I have one problem here, how do I align 2 buttons using the <s:submit> tag right in a single row? By default, the <s:submit> tag will create a row for each button. I want the 2 buttons to appear on the same row.

Thanks!

How to do|

You must use CSS =)
====part of css===
input.button{
float:left;
}
======end of css ======
use this css class for both buttons and you'll get what you want=)

Aligning Submit Buttons

Using this theme you can have as many submit buttons as will fit on a row. If you look at the sample you'll see that it takes an argument for the number of columns and its alignment.

Mark

Sample App

Hello, Mark.
First, thanks for the awesome howto's. I'm curently doing some webworking but hadn't enough time to get into all that complex stuff like themes and components; so your tutorial is big help for me, you should try to add links to them to the struts 2 project site imho.

Anyway, what about the sample app link you mentioned ? I didnt managed to find any on this page. Can you post it here ?

Regards, Sergey Pariev.

sx:datetimepicker with qxhtml theme

Hi,
I m using qxhtml theme and using struts core 2.1.6 with dojo support. I am trying to place two datatimepicker into row by
example

s:datetimepicker with qxhtml theme

Hi, for thise propose I use this tag:

Maybe you will have change this line in the template/qxhtml/datepicker.ftl:

for

if you are using struts2-core-2.0.11

s:datetimepicker with qxhtml theme

sorry the above post it's not complete, try

s:datetimepicker template="datepicker" label="fecha" theme="qxhtml"
s:param name="labelcolspan" value="%{2}"
s:param name="inputcolspan" value="%{2}"
s:datetimepicker

and change
include "/${parameters.templateDir}/simple/datepicker.ftl"

for

include "/${parameters.templateDir}/simple/datetimepicker.ftl"

Dynamically set the cssClass

I have textfield in the form and it should be editable/read only bases on the user role.
I am all set with the editable/read only functionality by setting the readonly attribute.

The requirement is that I need to set the gray backgroud color if the field is readonly.

I have defined like this in the css file

.readonly {
color: #000000;
background-color: #ccddee;
font-style: italic;
}
.regular {
color: #000000;
background-color: white;
font-style: normal;
}

it seems the cssClass attribute only accepts only string value. I cannot put regular expression for cssClass.

What is best way to accomplish this?

I appreciate your help.

Thanks,
Mohan

hello

Thanks, for the good articles...I am very intiresting..