You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by mu...@apache.org on 2007/03/03 06:49:21 UTC

svn commit: r514083 [2/49] - in /struts/struts2/trunk/plugins/dojo: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/struts2/ src/main/java/org/apache/struts2/components/ src/main/java/org/apache/st...

Added: struts/struts2/trunk/plugins/dojo/pom.xml
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/pom.xml?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/pom.xml (added)
+++ struts/struts2/trunk/plugins/dojo/pom.xml Fri Mar  2 21:48:54 2007
@@ -0,0 +1,198 @@
+<?xml version="1.0"?>
+<project>
+    <parent>
+        <artifactId>struts2-plugins</artifactId>
+        <groupId>org.apache.struts</groupId>
+        <version>2.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.struts</groupId>
+    <artifactId>struts2-dojo-plugin</artifactId>
+    <name>Struts2 Dojo Plugin</name>
+
+    <scm>
+        <connection>
+            scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/dojo/
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/plugins/dojo/
+        </developerConnection>
+        <url>
+            http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/plugins/dojo/
+        </url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.myfaces.tobago</groupId>
+                <artifactId>maven-apt-plugin</artifactId>
+                <configuration>
+                    <A>
+                        uri=/struts-dojo-tags,tlibVersion=2.2.3,jspVersion=1.2,shortName=sx,displayName="Struts
+                        Dojo Tags",
+                        outFile=${basedir}/target/classes/META-INF/struts-dojo-tags.tld,
+                        description="Struts AJAX tags based on Dojo.",
+                        outTemplatesDir=${basedir}/../../core/src/site/resources/tags/ajax
+                    </A>
+                    <resourceTargetPath>target</resourceTargetPath>
+                    <fork>false</fork>
+                    <force>true</force>
+                    <nocompile>true</nocompile>
+                    <showWarnings>true</showWarnings>
+                    <factory>
+                        org.apache.struts.annotations.taglib.apt.TLDAnnotationProcessorFactory
+                    </factory>
+                    <target>1.5</target>
+                    <includes>
+                        <include>**/*.java</include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>
+                        <goals>
+                            <goal>execute</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <dependencies>
+        <!-- Core -->
+        <dependency>
+            <groupId>org.apache.struts</groupId>
+            <artifactId>struts2-core</artifactId>
+            <version>${pom.version}</version>
+        </dependency>
+
+        <!-- JSP API -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>jsp-api</artifactId>
+            <version>2.0</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- Velocity -->
+        <dependency>
+            <groupId>velocity</groupId>
+            <artifactId>velocity</artifactId>
+            <version>1.4</version>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- Test dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>compile</scope>
+            <version>3.8.1</version>
+            <!-- has to be compile for StrutsTestCase, which is part of the base package so others can write unit tests -->
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>5.1</version>
+            <optional>true</optional>
+            <classifier>jdk15</classifier>
+        </dependency>
+
+        <dependency>
+            <groupId>jmock</groupId>
+            <artifactId>jmock</artifactId>
+            <version>1.0.1</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <version>2.0</version>
+            <scope>test</scope>
+        </dependency>
+        <!--dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymockclassextension</artifactId>
+            <version>1.1</version>
+            <scope>test</scope>
+            <exclusions>
+            <exclusion>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            </exclusion>
+            </exclusions>
+            </dependency-->
+
+        <dependency>
+            <groupId>jmock</groupId>
+            <artifactId>jmock-cglib</artifactId>
+            <version>1.0.1</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>mockobjects</groupId>
+            <artifactId>mockobjects-core</artifactId>
+            <version>0.09</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>mockobjects</groupId>
+            <artifactId>mockobjects-jdk1.3</artifactId>
+            <version>0.09</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>mockobjects</groupId>
+            <artifactId>mockobjects-alt-jdk1.3</artifactId>
+            <version>0.09</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>mockobjects</groupId>
+            <artifactId>mockobjects-alt-jdk1.3-j2ee1.3</artifactId>
+            <version>0.09</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>mockobjects</groupId>
+            <artifactId>mockobjects-jdk1.3-j2ee1.3</artifactId>
+            <version>0.09</version>
+            <scope>test</scope>
+        </dependency>
+
+
+        <!-- Mocks for unit testing (by Spring) -->
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-mock</artifactId>
+            <version>1.2.8</version>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>1.2.8</version>
+            <scope>test</scope>
+        </dependency>
+        
+         <!-- struts-annotations must be in compile scope for maven-apt-plugin to
+        function correctly. Marking it optional to exclude it from transitive
+        dependency resolution -->
+        <dependency>
+            <groupId>org.apache.struts</groupId>
+            <artifactId>struts-annotations</artifactId>
+            <version>1.0.2-SNAPSHOT</version>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/AbstractRemoteCallUIBean.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/AbstractRemoteCallUIBean.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/AbstractRemoteCallUIBean.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/AbstractRemoteCallUIBean.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,171 @@
+/*
+ * $Id: AbstractRemoteCallUIBean.java 508285 2007-02-16 02:42:24Z musachy $
+ *
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * AbstractRemoteCallUIBean is superclass for all components dealing with remote
+ * calls.
+ */
+@StrutsTagSkipInheritance
+public abstract class AbstractRemoteCallUIBean extends ClosingUIBean implements RemoteUICallBean {
+
+    protected String href;
+    protected String errorText;
+    protected String afterLoading;
+    protected String beforeLoading;
+    protected String executeScripts;
+    protected String loadingText;
+    protected String listenTopics;
+    protected String handler;
+    protected String formId;
+    protected String formFilter;
+    protected String notifyTopics;
+    protected String showErrorTransportText;
+    protected String indicator;
+    protected String showLoadingText;
+
+    public AbstractRemoteCallUIBean(ValueStack stack, HttpServletRequest request,
+            HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    public void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if (href != null)
+            addParameter("href", findString(href));
+        if (errorText != null)
+            addParameter("errorText", findString(errorText));
+        if (loadingText != null)
+            addParameter("loadingText", findString(loadingText));
+        if (afterLoading != null)
+            addParameter("afterLoading", findString(afterLoading));
+        if (beforeLoading != null)
+            addParameter("beforeLoading", findString(beforeLoading));
+        if (executeScripts != null)
+            addParameter("executeScripts", findValue(executeScripts, Boolean.class));
+        if (listenTopics != null)
+            addParameter("listenTopics", findValue(listenTopics, String.class));
+        if (notifyTopics != null)
+            addParameter("notifyTopics", findValue(notifyTopics, String.class));
+        if (handler != null)
+            addParameter("handler", findString(handler));
+        if (formId != null)
+            addParameter("formId", findString(formId));
+        if (formFilter != null)
+            addParameter("formFilter", findString(formFilter));
+        if (indicator != null)
+            addParameter("indicator", findString(indicator));
+        if (showErrorTransportText != null)
+            addParameter("showErrorTransportText", findValue(showErrorTransportText, Boolean.class));
+        else
+            addParameter("showErrorTransportText", true);
+        if (showLoadingText != null)
+            addParameter("showLoadingText", findString(showLoadingText));
+    }
+
+
+    @StrutsTagAttribute(description="Topic that will trigger the remote call")
+    public void setListenTopics(String listenTopics) {
+        this.listenTopics = listenTopics;
+    }
+
+    @StrutsTagAttribute(description="The URL to call to obtain the content. Note: If used with ajax context, the value must be set as an url tag value.")
+    public void setHref(String href) {
+        this.href = href;
+    }
+
+
+    @StrutsTagAttribute(description="The text to display to the user if the is an error fetching the content")
+    public void setErrorText(String errorText) {
+        this.errorText = errorText;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.struts2.components.RemoteUICallBean#setAfterLoading(java.lang.String)
+     */
+    public void setAfterLoading(String afterLoading) {
+        this.afterLoading = afterLoading;
+    }
+
+
+    /* (non-Javadoc)
+     * @see org.apache.struts2.components.RemoteUICallBean#setBeforeLoading(java.lang.String)
+     */
+    public void setBeforeLoading(String beforeLoading) {
+        this.beforeLoading = beforeLoading;
+    }
+
+
+    @StrutsTagAttribute(description="Javascript code in the fetched content will be executed", type="Boolean", defaultValue="false")
+    public void setExecuteScripts(String executeScripts) {
+        this.executeScripts = executeScripts;
+    }
+
+    @StrutsTagAttribute(description="Text to be shown while content is being fetched", defaultValue="Loading...")
+    public void setLoadingText(String loadingText) {
+        this.loadingText = loadingText;
+    }
+
+
+    @StrutsTagAttribute(description="Javascript function name that will make the request")
+    public void setHandler(String handler) {
+        this.handler = handler;
+    }
+
+
+    @StrutsTagAttribute(description="Function name used to filter the fields of the form.")
+    public void setFormFilter(String formFilter) {
+        this.formFilter = formFilter;
+    }
+
+    @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
+    public void setFormId(String formId) {
+        this.formId = formId;
+    }
+
+    @StrutsTagAttribute(description="Topics that will published when the remote call completes")
+    public void setNotifyTopics(String notifyTopics) {
+        this.notifyTopics = notifyTopics;
+    }
+
+
+    @StrutsTagAttribute(description="Set whether errors will be shown or not", type="Boolean", defaultValue="true")
+    public void setShowErrorTransportText(String showError) {
+        this.showErrorTransportText = showError;
+    }
+
+    @StrutsTagAttribute(description="Id of element that will be shown while making request")
+    public void setIndicator(String indicator) {
+        this.indicator = indicator;
+    }
+
+    @StrutsTagAttribute(description="Show loading text on targets", type="Boolean", defaultValue="true")
+    public void setShowLoadingText(String showLoadingText) {
+        this.showLoadingText = showLoadingText;
+    }
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Anchor.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Anchor.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Anchor.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Anchor.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,171 @@
+/*
+ * $Id: Anchor.java 508285 2007-02-16 02:42:24Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ *
+ * A tag that creates a HTML &lt;a href='' /&gt; that when clicked calls a URL remote XMLHttpRequest call via the dojo
+ * framework.<p/>
+ *
+ * <!-- START SNIPPET: ajaxJavadoc -->
+ * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
+ * <ul>
+ *      <li>href</li>
+ *      <li>errorText</li>
+ *      <li>listenTopics</li>
+ *      <li>notifyTopics</li>
+ *      <li>executeScripts</li>
+ *      <li>loadingText</li>
+ *      <li>listenTopics</li>
+ *      <li>handler</li>
+ *      <li>formId</li>
+ *      <li>formFilter</li>
+ *      <li>targets</li>
+ *      <li>showErrorTransportText</li>
+ *      <li>targets</li>
+ *      <li>indicator</li>
+ * </ul>
+ * 'resultDivId' Deprecated. Use targets.<p/>
+ * 'targets' is a list of element ids whose content will be updated with the
+ * text returned from request.<p/>
+ * 'errorText' is the text that will be displayed when there is an error making the request.<p/>
+ * 'onLoadJS' Deprecated. Use 'notifyTopics'.<p/>
+ * 'preInvokeJS' Deprecated. Use 'notifyTopics'.<p/>
+ * 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
+ * 'loadingText' is the text that will be displayed on the 'targets' elements while making the
+ * request.<p/>
+ * 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
+ * and dom node are passed as parameters).<p/>
+ * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
+ * in the request.<p/>
+ * 'formFilter' is the name of a function which will be used to filter the fields that will be
+ * seralized. This function takes as a parameter the element and returns true if the element
+ * should be included.<p/>
+ * 'listenTopics' comma separated list of topics names, that will trigger a request
+ * 'indicator' element to be shown while the request executing
+ * 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
+ * 'showLoadingText' show loading text on targets</p>
+ * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
+ * <ul>
+ *      <li>data: html or json object when type='load' or type='error'</li>
+ *      <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
+ *      <li>request: request javascript object, when type='load' or type='error'</li>
+ * </ul>
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <p/> <b>Examples</b>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example1 -->
+ * &lt;s:a id="link1" theme="ajax" href="/DoIt.action" errorText="An error ocurred" loadingText="Loading..."&gt;
+ *     &lt;img border="none" src="&lt;%=request.getContextPath()%&gt;/images/delete.gif"/&gt;
+ *     &lt;s:param name="id" value="1"/&gt;
+ * &lt;/s:a&gt;
+ * <!-- END SNIPPET: example1 -->
+ * </pre>
+ *
+ * </p>
+ *
+ * <!-- START SNIPPET: exampledescription1 -->
+ *
+ * Results in
+ *
+ * <!-- END SNIPPET: exampledescription1 -->
+ *
+ * </p>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example2 -->
+ * &lt;a dojoType="BindAnchor" executeScripts="true" id="link1" href="/DoIt.action?id=1" errorText="An error ocurred"&gt;&lt;/a&gt;
+ * <!-- END SNIPPET: example2 -->
+ * </pre>
+ *
+ * </p>
+ *
+ * <!-- START SNIPPET: exampledescription2 -->
+ *
+ * Here is an example that uses the beforeLoading. This example is in altSyntax=true:
+ *
+ * <!-- END SNIPPET: exampledescription2 -->
+ *
+ * </p>
+ *
+ * <pre>
+ * <!-- START SNIPPET: example3 -->
+ * &lt;s:a id="test" theme="ajax" href="/simpeResult.action" beforeLoading="confirm('Are you sure?')"&gt;
+ *  A
+ * &lt;/s:a&gt;
+ * <!-- END SNIPPET: example3 -->
+ * </pre>
+ *
+ */
+@StrutsTag(name="a", tldTagClass="org.apache.struts2.views.jsp.ui.AnchorTag", description="Render a HTML href element that when clicked can optionally call a URL via remote XMLHttpRequest and updates its targets")
+public class Anchor extends AbstractRemoteCallUIBean {
+    public static final String OPEN_TEMPLATE = "a";
+    public static final String TEMPLATE = "a-close";
+    public static final String COMPONENT_NAME = Anchor.class.getName();
+
+    protected String targets;
+
+    public Anchor(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    public String getDefaultOpenTemplate() {
+        return OPEN_TEMPLATE;
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE;
+    }
+
+    public void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if(targets != null)
+            addParameter("targets", findString(targets));
+    }
+
+    @StrutsTagAttribute(description="Comma delimited list of ids of the elements whose content will be updated")
+    public void setTargets(String targets) {
+        this.targets = targets;
+    }
+
+    @StrutsTagAttribute(name="onLoadJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
+    public void setAfterLoading(String afterLoading) {
+        this.afterLoading = afterLoading;
+    }
+
+
+    @StrutsTagAttribute(name="preInvokeJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute before reload")
+    public void setBeforeLoading(String beforeLoading) {
+        this.beforeLoading = beforeLoading;
+    }
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Autocompleter.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Autocompleter.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Autocompleter.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Autocompleter.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,302 @@
+/*
+ * $Id: Autocompleter.java 510785 2007-02-23 03:05:33Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * <p>The autocomplete tag is a combobox that can autocomplete text entered on the input box.
+ * When used on the "simple" theme, the autocompleter can be used like the ComboBox.
+ * When used on the "ajax" theme, the list can be retieved from an action. </p>
+ * <!-- END SNIPPET: javadoc -->
+ * <!-- START SNIPPET: ajaxJavadoc -->
+ * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
+ * <ul>
+ *      <li>href</li>
+ *      <li>errorText</li>
+ *      <li>listenTopics</li>
+ *      <li>notifyTopics</li>
+ *      <li>listenTopics</li>
+ *      <li>formId</li>
+ *      <li>formFilter</li>
+ *      <li>indicator</li>
+ *      <li>loadOnTextChange</li>
+ *      <li>loadMinimumCount</li>
+ *      <li>showDownArrow</li>
+ *      <li>searchType</li>
+ * </ul>
+ * 'dropdownWidth' width in pixels of the drodpdown, same as autocompleter's width by default<p/>
+ * 'dropdownHeight' height in pixels of the drodown, 120 px by default<p/>
+ * 'forceValidOption' if invalid option is selected, clear autocompleter's text when focus is lost<p/>
+ * 'autoComplete', if true, make suggestions on the textbox<p/>
+ * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
+ * in the request.<p/>
+ * 'formFilter' is the name of a function which will be used to filter the fields that will be
+ * seralized. This function takes as a parameter the element and returns true if the element
+ * should be included.<p/>
+ * 'listenTopics' comma separated list of topics names, that will trigger a request
+ * 'indicator' element to be shown while the request executing
+ * 'showErrorTransportText': whether errors should be displayed (on 'targets')<p/>
+ * 'loadOnTextChange' options will be reloaded everytime a character is typed on the textbox<p/>
+ * 'loadMinimumCount' minimum number of characters that will force the content to be loaded<p/>
+ * 'showDownError' show or hide the down arrow button<p/>
+ * 'searchType' how the search must be performed, options are: "startstring", "startword" and "substring"<p/>
+ * 'keyName' name of the field to which the selected key will be assigned<p/>
+ * 'iconPath' path of icon used for the dropdown<p/>
+ * 'templateCssPath' path to css file used to customize Dojo's widget<p/>
+ * 'dataFieldName' name of the field to be used as the list in the returned JSON string<p/>
+ * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
+ * <ul>
+ *      <li>data: selected value when type='valuechanged'</li>
+ *      <li>type: 'before' before the request is made, 'valuechanged' when selection changes, 'load' when the request succeeds, or 'error' when it fails</li>
+ *      <li>request: request javascript object, when type='load' or type='error'</li>
+ * <ul>
+ *<!-- END SNIPPET: ajaxJavadoc -->
+ *
+ *<!-- START SNIPPET: example -->
+ *<p>Autocompleter that gets its list from an action:</p>
+ *&lt;s:autocompleter name="test"  href="%{jsonList}" autoComplete="false"/&gt;
+ *<br/>
+ **<p>Autocompleter that uses a list:</p>
+ *&lt;s:autocompleter name="test"  list="{'apple','banana','grape','pear'}" autoComplete="false"/&gt;
+ *<br/>
+ *<!-- END SNIPPET: example -->
+ */
+@StrutsTag(name="autocompleter", tldTagClass="org.apache.struts2.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
+@StrutsTagSkipInheritance
+public class Autocompleter extends ComboBox {
+    public static final String TEMPLATE = "autocompleter";
+    final private static String COMPONENT_NAME = Autocompleter.class.getName();
+
+    protected String forceValidOption;
+    protected String searchType;
+    protected String autoComplete;
+    protected String delay;
+    protected String disabled;
+    protected String href;
+    protected String dropdownWidth;
+    protected String dropdownHeight;
+    protected String formId;
+    protected String formFilter;
+    protected String listenTopics;
+    protected String notifyTopics;
+    protected String indicator;
+    protected String loadOnTextChange;
+    protected String loadMinimumCount;
+    protected String showDownArrow;
+    protected String templateCssPath;
+    protected String iconPath;
+    protected String keyName;
+    protected String dataFieldName;
+    
+    public Autocompleter(ValueStack stack, HttpServletRequest request,
+            HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE;
+    }
+
+    public String getComponentName() {
+        return COMPONENT_NAME;
+    }
+
+
+    public void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if (forceValidOption != null)
+            addParameter("forceValidOption", findValue(forceValidOption,
+                    Boolean.class));
+        if (searchType != null) {
+            String type =  findString(searchType);
+            if(type != null)
+                addParameter("searchType", type.toUpperCase());
+        }
+        if (autoComplete != null)
+            addParameter("autoComplete", findValue(autoComplete, Boolean.class));
+        if (delay != null)
+            addParameter("delay", findValue(delay, Integer.class));
+        if (disabled != null)
+            addParameter("disabled", findValue(disabled, Boolean.class));
+        if (href != null) {
+            addParameter("href", findString(href));
+            addParameter("mode", "remote");
+        }
+        if (dropdownHeight != null)
+            addParameter("dropdownHeight", findValue(dropdownHeight, Integer.class));
+        if (dropdownWidth != null)
+            addParameter("dropdownWidth", findValue(dropdownWidth, Integer.class));
+        if (formFilter != null)
+          addParameter("formFilter", findString(formFilter));
+        if (formId != null)
+          addParameter("formId", findString(formId));
+        if (listenTopics != null)
+          addParameter("listenTopics", findString(listenTopics));
+        if (notifyTopics != null)
+          addParameter("notifyTopics", findString(notifyTopics));
+        if (indicator != null)
+            addParameter("indicator", findString(indicator));
+        if (loadOnTextChange != null)
+            addParameter("loadOnTextChange", findValue(loadOnTextChange, Boolean.class));
+        if (loadMinimumCount != null)
+            addParameter("loadMinimumCount", findValue(loadMinimumCount, Integer.class));
+        if (showDownArrow != null)
+            addParameter("showDownArrow", findValue(showDownArrow, Boolean.class));
+        else
+            addParameter("showDownArrow", Boolean.TRUE);
+        if(templateCssPath != null)
+            addParameter("templateCssPath", findString(templateCssPath));
+        if(iconPath != null)
+            addParameter("iconPath", findString(iconPath));
+        if(dataFieldName != null)
+        addParameter("dataFieldName", findString(dataFieldName));
+        if(keyName != null)
+            addParameter("keyName", findString(keyName));
+        else {
+            keyName = name + "Key";
+            addParameter("keyName", findString(keyName));
+        }
+        
+        String keyNameExpr = "%{" + keyName + "}";
+        addParameter("key", findString(keyNameExpr));
+    }
+
+    protected Object findListValue() {
+        return (list != null) ? findValue(list, Object.class) : null;
+    }
+
+    @StrutsTagAttribute(description="Whether autocompleter should make suggestion on the textbox", type="Boolean", defaultValue="false")
+    public void setAutoComplete(String autoComplete) {
+        this.autoComplete = autoComplete;
+    }
+
+    @StrutsTagAttribute(description="Enable or disable autocompleter", type="Boolean", defaultValue="false")
+    public void setDisabled(String disabled) {
+        this.disabled = disabled;
+    }
+
+    @StrutsTagAttribute(description="Force selection to be one of the options", type="Boolean", defaultValue="false")
+    public void setForceValidOption(String forceValidOption) {
+        this.forceValidOption = forceValidOption;
+    }
+
+    @StrutsTagAttribute(description="The URL used to load the options")
+    public void setHref(String href) {
+        this.href = href;
+    }
+
+    @StrutsTagAttribute(description="Delay before making the search", type="Integer", defaultValue="100")
+    public void setDelay(String searchDelay) {
+        this.delay = searchDelay;
+    }
+
+    @StrutsTagAttribute(description="how the search must be performed, options are: 'startstring', 'startword' " +
+                "and 'substring'", defaultValue="stringstart")
+    public void setSearchType(String searchType) {
+        this.searchType = searchType;
+    }
+
+    @StrutsTagAttribute(description="Dropdown's height in pixels", type="Integer", defaultValue="120")
+    public void setDropdownHeight(String height) {
+        this.dropdownHeight = height;
+    }
+
+    @StrutsTagAttribute(description="Dropdown's width", type="Integer", defaultValue="same as textbox")
+    public void setDropdownWidth(String width) {
+        this.dropdownWidth = width;
+    }
+
+    @StrutsTagAttribute(description="Function name used to filter the fields of the form")
+    public void setFormFilter(String formFilter) {
+      this.formFilter = formFilter;
+    }
+
+    @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
+    public void setFormId(String formId) {
+      this.formId = formId;
+    }
+
+    @StrutsTagAttribute(description="Topic that will trigger a reload")
+    public void setListenTopics(String listenTopics) {
+      this.listenTopics = listenTopics;
+    }
+
+    @StrutsTagAttribute(description="Topics that will be published when content is reloaded")
+    public void setNotifyTopics(String onValueChangedPublishTopic) {
+      this.notifyTopics = onValueChangedPublishTopic;
+    }
+
+    @StrutsTagAttribute(description="Id of element that will be shown while request is made")
+    public void setIndicator(String indicator) {
+        this.indicator = indicator;
+    }
+
+    @StrutsTagAttribute(description="Minimum number of characters that will force the content to be loaded", type="Integer", defaultValue="3")
+    public void setLoadMinimumCount(String loadMinimumCount) {
+        this.loadMinimumCount = loadMinimumCount;
+    }
+
+    @StrutsTagAttribute(description="Options will be reloaded everytime a character is typed on the textbox", type="Boolean", defaultValue="true")
+    public void setLoadOnTextChange(String loadOnType) {
+        this.loadOnTextChange = loadOnType;
+    }
+
+    @StrutsTagAttribute(description="Show or hide the down arrow button", type="Boolean", defaultValue="true")
+    public void setShowDownArrow(String showDownArrow) {
+        this.showDownArrow = showDownArrow;
+    }
+
+    // Override as not required
+    @StrutsTagAttribute(description="Iteratable source to populate from.")
+    public void setList(String list) {
+        super.setList(list);
+    }
+    
+    @StrutsTagAttribute(description="Template css path")
+    public void setTemplateCssPath(String templateCssPath) {
+        this.templateCssPath = templateCssPath;
+    }
+    
+    @StrutsTagAttribute(description="Path to icon used for the dropdown")
+    public void setIconPath(String iconPath) {
+        this.iconPath = iconPath;
+    }
+    
+    @StrutsTagAttribute(description="Name of the field to which the selected key will be assigned")
+    public void setKeyName(String keyName) {
+       this.keyName = keyName;
+    }
+
+    @StrutsTagAttribute(description="Name of the field in the returned JSON object that contains the data array", defaultValue="Value specified in 'name'")
+    public void setDataFieldName(String dataFieldName) {
+        this.dataFieldName = dataFieldName;
+    }
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/DateTimePicker.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/DateTimePicker.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/DateTimePicker.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/DateTimePicker.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,324 @@
+/*
+ * $Id: DateTimePicker.java 512580 2007-02-28 02:48:06Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * <p>
+ * Renders a date/time picker in a dropdown container.
+ * </p>
+ * <p>
+ * A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month,
+ * and/or year.
+ * </p>
+ *
+ * <p>
+ * It is possible to customize the user-visible formatting with either the
+ * 'formatLength' (long, short, medium or full) or 'displayFormat' attributes. By defaulty current
+ * locale will be used.</p>
+ * </p>
+ * 
+ * Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):-
+ * <table border="1">
+ *   <tr>
+ *      <td>Format</td>
+ *      <td>Description</td>
+ *   </tr>
+ *   <tr>
+ *      <td>d</td>
+ *      <td>Day of the month</td>
+ *   </tr>
+ *   <tr>
+ *      <td>D</td>
+ *      <td>Day of year</td>
+ *   </tr>
+ *   <tr>
+ *      <td>M</td>
+ *      <td>Month - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.</td>
+ *   </tr>
+ *   <tr>
+ *      <td>h</td>
+ *      <td>Hour [1-12].</td>
+ *   </tr>
+ *   <tr>
+ *      <td>H</td>
+ *      <td>Hour [0-23].</td>
+ *   </tr>
+ *   <tr>
+ *      <td>m</td>
+ *      <td>Minute. Use one or two for zero padding.</td>
+ *   </tr>
+ *   <tr>
+ *      <td>s</td>
+ *      <td>Second. Use one or two for zero padding.</td>
+ *   </tr>
+ * </table>
+ * 
+ * <p>
+ * The value sent to the server is
+ * typically a locale-independent value in a hidden field as defined by the name
+ * attribute. RFC3339 representation is the format used.
+ * </p>
+ *
+ * <p/>
+ *
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <b>Examples</b>
+ *
+ * <pre>
+ * <!-- START SNIPPET: expl1 -->
+ *
+ * Example 1:
+ *     &lt;s:datetimepicker name="order.date" label="Order Date" /&gt;
+ * Example 2:
+ *     &lt;s:datetimepicker name="delivery.date" label="Delivery Date" format="yyyy-MM-dd"  /&gt;
+ *
+ * <!-- END SNIPPET: expl1 -->
+ * </pre>
+ * <p/>
+ *
+ * <!-- START SNIPPET: expldesc2 -->
+ *
+ * The css could be changed by using the following :-
+ *
+ * <!-- END SNIPPET: expldesc2 -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: expl2 -->
+ *
+ * &lt;s:datetimepicker name="birthday" label="Birthday" templateCss="...." /&gt;
+ *
+ * <!-- END SNIPPET: expl2 -->
+ * </pre>
+ *
+ */
+@StrutsTag(name="datetimepicker", tldTagClass="org.apache.struts2.views.jsp.ui.DateTimePickerTag", description="Render datetimepicker")
+@StrutsTagSkipInheritance
+public class DateTimePicker extends UIBean {
+
+    final public static String TEMPLATE = "datetimepicker";
+    final private static SimpleDateFormat RFC3339_FORMAT = new SimpleDateFormat(
+    "yyyy-MM-dd'T'HH:mm:ss");
+    final protected static Log LOG = LogFactory.getLog(DateTimePicker.class);
+    
+    protected String iconPath;
+    protected String formatLength;
+    protected String displayFormat;
+    protected String toggleType;
+    protected String toggleDuration;
+    protected String type;
+
+    protected String displayWeeks;
+    protected String adjustWeeks;
+    protected String startDate;
+    protected String endDate;
+    protected String weekStartsOn;
+    protected String staticDisplay;
+    protected String dayWidth;
+    protected String language;
+    protected String templateCssPath;
+
+    public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE;
+    }
+
+    public void evaluateParams() {
+        super.evaluateParams();
+
+        if(displayWeeks != null)
+            addParameter("displayWeeks", findString(displayWeeks));
+        if(adjustWeeks != null)
+            addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class));
+        if(startDate != null)
+            addParameter("startDate", findString(startDate));
+        if(endDate != null)
+            addParameter("endDate", findString(endDate));
+        if(weekStartsOn != null)
+            addParameter("weekStartsOn", findString(weekStartsOn));
+        if(staticDisplay != null)
+            addParameter("staticDisplay", findValue(staticDisplay, Boolean.class));
+        if(dayWidth != null)
+            addParameter("dayWidth", findValue(dayWidth, Integer.class));
+        if(language != null)
+            addParameter("language", findString(language));
+        if(value != null)
+            addParameter("value", findString(value));
+        if(iconPath != null)
+            addParameter("iconPath", findString(iconPath));
+        if(formatLength != null)
+            addParameter("formatLength", findString(formatLength));
+        if(displayFormat != null)
+            addParameter("displayFormat", findString(displayFormat));
+        if(toggleType != null)
+            addParameter("toggleType", findString(toggleType));
+        if(toggleDuration != null)
+            addParameter("toggleDuration", findValue(toggleDuration,
+                    Integer.class));
+        if(type != null)
+            addParameter("type", findString(type));
+        else
+            addParameter("type", "date");
+        if(templateCssPath != null)
+            addParameter("templateCssPath", findString(templateCssPath));
+        
+        // format the value to RFC 3399
+        if(parameters.containsKey("value")) {
+            parameters.put("nameValue", format(parameters.get("value")));
+        } else {
+            if(name != null) {
+                String expr = name;
+                if(altSyntax()) {
+                    expr = "%{" + expr + "}";
+                }
+                addParameter("nameValue", format(findValue(expr)));
+            }
+        }
+    }
+
+    @StrutsTagAttribute(description="If true, weekly size of calendar changes to acomodate the month if false," +
+                " 42 day format is used", type="Boolean", defaultValue="false")
+    public void setAdjustWeeks(String adjustWeeks) {
+        this.adjustWeeks = adjustWeeks;
+    }
+
+    @StrutsTagAttribute(description="How to render the names of the days in the header(narrow, abbr or wide)", defaultValue="narrow")
+    public void setDayWidth(String dayWidth) {
+        this.dayWidth = dayWidth;
+    }
+
+    @StrutsTagAttribute(description="Total weeks to display", type="Integer", defaultValue="6")
+    public void setDisplayWeeks(String displayWeeks) {
+        this.displayWeeks = displayWeeks;
+    }
+
+    @StrutsTagAttribute(description="Last available date in the calendar set", type="Date", defaultValue="2941-10-12")
+    public void setEndDate(String endDate) {
+        this.endDate = endDate;
+    }
+
+    @StrutsTagAttribute(description="First available date in the calendar set", type="Date", defaultValue="1492-10-12")
+    public void setStartDate(String startDate) {
+        this.startDate = startDate;
+    }
+
+    @StrutsTagAttribute(description="Disable all incremental controls, must pick a date in the current display", type="Boolean", defaultValue="false")
+    public void setStaticDisplay(String staticDisplay) {
+        this.staticDisplay = staticDisplay;
+    }
+
+    @StrutsTagAttribute(description="Adjusts the first day of the week 0==Sunday..6==Saturday", type="Integer", defaultValue="0")
+    public void setWeekStartsOn(String weekStartsOn) {
+        this.weekStartsOn = weekStartsOn;
+    }
+
+    @StrutsTagAttribute(description="Language to display this widget in", defaultValue="brower's specified preferred language")
+    public void setLanguage(String language) {
+        this.language = language;
+    }
+    
+    @StrutsTagAttribute(description="A pattern used for the visual display of the formatted date, e.g. dd/MM/yyyy")
+    public void setDisplayFormat(String displayFormat) {
+        this.displayFormat = displayFormat;
+    }
+
+    @StrutsTagAttribute(description="Type of formatting used for visual display. Possible values are " +
+                "long, short, medium or full", defaultValue="short")
+    public void setFormatLength(String formatLength) {
+        this.formatLength = formatLength;
+    }
+
+    @StrutsTagAttribute(description="Path to icon used for the dropdown")
+    public void setIconPath(String iconPath) {
+        this.iconPath = iconPath;
+    }
+
+    @StrutsTagAttribute(description="Duration of toggle in milliseconds", type="Integer", defaultValue="100")
+    public void setToggleDuration(String toggleDuration) {
+        this.toggleDuration = toggleDuration;
+    }
+
+    @StrutsTagAttribute(description="Defines the type of the picker on the dropdown. Possible values are 'date'" +
+                " for a DateTimePicker, and 'time' for a timePicker", defaultValue="date")
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    @StrutsTagAttribute(description="oggle type of the dropdown. Possible values are plain,wipe,explode,fade", defaultValue="plain")
+    public void setToggleType(String toggleType) {
+        this.toggleType = toggleType;
+    }
+    
+    @StrutsTagAttribute(description="Template css path")
+    public void setTemplateCssPath(String templateCssPath) {
+        this.templateCssPath = templateCssPath;
+    }
+    
+    private String format(Object obj) {
+        if(obj == null)
+            return null;
+
+        if(obj instanceof Date) {
+            return RFC3339_FORMAT.format((Date) obj);
+        } else {
+            // try to parse a date
+            String dateStr = obj.toString();
+            if(dateStr.equalsIgnoreCase("today"))
+                return RFC3339_FORMAT.format(new Date());
+
+            try {
+                Date date = null;
+                if(this.displayFormat != null) {
+                    SimpleDateFormat format = new SimpleDateFormat(
+                            (String) getParameters().get("displayFormat"));
+                    date = format.parse(dateStr);
+                    return RFC3339_FORMAT.format(date);
+                } else {
+                    // last resource to assume already in correct/default format
+                    return dateStr;
+                }
+            } catch (ParseException e) {
+                LOG.error("Could not parse date", e);
+                return dateStr;
+            }
+        }
+    }
+
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Div.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Div.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Div.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Div.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,193 @@
+/*
+ * $Id: Div.java 511300 2007-02-24 16:41:38Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * The div tag when used on the ajax theme, provides a remote call
+ * from the current page to update a section of content without having to refresh the entire page.
+ * <p>
+ * It creates a HTML &lt;DIV /&gt; that obtains it's content via a remote XMLHttpRequest call via
+ * the dojo framework.
+ * </p>
+ * <div>
+ * <!-- START SNIPPET: ajaxJavadoc -->
+ * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
+ * <ul>
+ *      <li>href</li>
+ *      <li>errorText</li>
+ *      <li>afterLoading</li>
+ *      <li>executeScripts</li>
+ *      <li>loadingText</li>
+ *      <li>listenTopics</li>
+ *      <li>handler</li>
+ *      <li>formId</li>
+ *      <li>formFilter</li>
+ *      <li>targets</li>
+ *      <li>notifyTopics</li>
+ *      <li>showErrorTransportText</li>
+ *      <li>indicator</li>
+ * </ul>
+ * 'targets' is a list of element ids whose content will be updated with the
+ * text returned from request.<p/>
+ * 'href' needs to be set as an url tag reference value.<p/>
+ * 'errorText' is the text that will be displayed when there is an error making the request.<p/>
+ * 'afterLoading' Deprecated. Use 'notifyTopics'.<p/>
+ * 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
+ * 'loadingText' is the text that will be displayed on the 'targets' elements while making the
+ * request.<p/>
+ * 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
+ * and dom node are passed as parameters).<p/>
+ * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
+ * in the request.<p/>
+ * 'formFilter' is the name of a function which will be used to filter the fields that will be
+ * seralized. This function takes as a parameter the element and returns true if the element
+ * should be included.<p/>
+ * 'updateFreq' sets(in milliseconds) the update interval.<p/>
+ * 'autoStart' if set to true(true by default) starts the timer automatically<p/>
+ * 'startTimerListenTopics' is a comma-separated list of topics used to start the timer<p/>
+ * 'stopTimerListenTopics' is a comma-separated list of topics used to stop the timer<p/>
+ * 'listenTopics' comma separated list of topics names, that will trigger a request<p/>
+ * 'indicator' element to be shown while the request executing<p/>
+ * 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
+ * 'showLoadingText' show loading text on targets</p>
+ * 'separateScript' Run scripts in a separate scope, unique for each Div<p/>
+ * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
+ * <ul>
+ *      <li>data: html or json object when type='load' or type='error'</li>
+ *      <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
+ *      <li>request: request javascript object, when type='load' or type='error'</li>
+ * </ul>
+ * <!-- END SNIPPET: javadoc -->
+ * </div><p> <b>Examples</b>
+ *
+ * <pre>
+ *       <!-- START SNIPPET: example -->
+ * &lt;s:url id="url" action="AjaxTest" />
+ * &lt;s:div
+ *    id=&quot;once&quot;
+ *    theme=&quot;ajax&quot;
+ *    href=&quot;%{url}&quot;
+ *    loadingText=&quot;Loading...&quot;
+ *    listenTopics=&quot;/refresh&quot;
+ *    updateFreq=&quot;3000&quot;
+ *    autoStart=&quot;true&quot;
+ *    formId=&quot;form&quot;
+ *&gt;&lt;/s:div&gt;
+ *       <!-- END SNIPPET: example -->
+ * </pre>
+ * </p>
+ *
+ */
+@StrutsTag(name="div", tldTagClass="org.apache.struts2.views.jsp.ui.DivTag", description="Render HTML div providing content from remote call via AJAX")
+public class Div extends AbstractRemoteCallUIBean {
+
+    public static final String TEMPLATE = "div";
+    public static final String TEMPLATE_CLOSE = "div-close";
+    public static final String COMPONENT_NAME = Div.class.getName();
+
+    protected String updateFreq;
+    protected String autoStart;
+    protected String delay;
+    protected String startTimerListenTopics;
+    protected String stopTimerListenTopics;
+    protected String refreshOnShow;
+    protected String separateScripts;
+
+    public Div(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    public String getDefaultOpenTemplate() {
+        return TEMPLATE;
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE_CLOSE;
+    }
+
+    public void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if (updateFreq != null)
+            addParameter("updateFreq", findValue(updateFreq, Integer.class));
+        if (autoStart != null)
+            addParameter("autoStart", findValue(autoStart, Boolean.class));
+        if (refreshOnShow != null)
+            addParameter("refreshOnShow", findValue(refreshOnShow, Boolean.class));
+        if (delay != null)
+            addParameter("delay", findValue(delay, Integer.class));
+        if (startTimerListenTopics != null)
+            addParameter("startTimerListenTopics", findString(startTimerListenTopics));
+        if (stopTimerListenTopics != null)
+            addParameter("stopTimerListenTopics", findString(stopTimerListenTopics));
+        if (separateScripts != null)
+            addParameter("separateScripts", findValue(separateScripts, Boolean.class));
+    }
+
+    @StrutsTagAttribute(description="Start timer automatically", type="Boolean", defaultValue="true")
+    public void setAutoStart(String autoStart) {
+        this.autoStart = autoStart;
+    }
+
+    @StrutsTagAttribute(description="How long to wait before fetching the content (in milliseconds)",  type="Integer")
+    public void setDelay(String delay) {
+        this.delay = delay;
+    }
+
+    @StrutsTagAttribute(description="How often to reload the content (in milliseconds)", type="Integer")
+    public void setUpdateFreq(String updateInterval) {
+        this.updateFreq = updateInterval;
+    }
+
+    @StrutsTagAttribute(description="Topics that will start the timer (for autoupdate)")
+    public void setStartTimerListenTopics(String startTimerListenTopic) {
+        this.startTimerListenTopics = startTimerListenTopic;
+    }
+
+    @StrutsTagAttribute(description="Topics that will stop the timer (for autoupdate)")
+    public void setStopTimerListenTopics(String stopTimerListenTopic) {
+        this.stopTimerListenTopics = stopTimerListenTopic;
+    }
+
+    @StrutsTagAttribute(description="Content will be loaded when div becomes visible, used only inside tabbedPanel", type="Boolean", defaultValue="false")
+    public void setRefreshOnShow(String refreshOnShow) {
+        this.refreshOnShow = refreshOnShow;
+    }
+
+    @StrutsTagAttribute(description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
+    public void setAfterLoading(String afterLoading) {
+        this.afterLoading = afterLoading;
+    }
+
+    @StrutsTagAttribute(description="Run scripts in a separate scope, unique for each Div", defaultValue="true")
+    public void setSeparateScripts(String separateScripts) {
+        this.separateScripts = separateScripts;
+    }
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/RemoteUICallBean.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/RemoteUICallBean.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/RemoteUICallBean.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/RemoteUICallBean.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,54 @@
+/*
+ * $Id: RemoteUICallBean.java 508285 2007-02-16 02:42:24Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+
+public interface RemoteUICallBean {
+
+    void setListenTopics(String topics);
+
+    void setNotifyTopics(String topics);
+
+    void setHref(String href);
+
+    void setErrorText(String errorText);
+
+    void setAfterLoading(String afterLoading);
+
+    void setBeforeLoading(String beforeLoading);
+
+    void setExecuteScripts(String executeScripts);
+
+    void setLoadingText(String loadingText);
+
+    void setHandler(String handler);
+
+    void setFormFilter(String formFilter);
+
+    void setFormId(String formId);
+
+    void setShowErrorTransportText(String showError);
+
+    void setShowLoadingText(String showLoadingText);
+
+    void setIndicator(String indicator);
+
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Submit.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Submit.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Submit.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/Submit.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,340 @@
+/*
+ * $Id: Submit.java 508285 2007-02-16 02:42:24Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import java.io.Writer;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * Render a submit button. The submit tag is used together with the form tag to provide asynchronous form submissions.
+ * The submit can have three different types of rendering:
+ * <ul>
+ * <li>input: renders as html &lt;input type="submit"...&gt;</li>
+ * <li>image: renders as html &lt;input type="image"...&gt;</li>
+ * <li>button: renders as html &lt;button type="submit"...&gt;</li>
+ * </ul>
+ * Please note that the button type has advantages by adding the possibility to seperate the submitted value from the
+ * text shown on the button face, but has issues with Microsoft Internet Explorer at least up to 6.0
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <p/> <b>Examples</b>
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * &lt;s:submit value="%{'Submit'}" /&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ * <pre>
+ * <!-- START SNIPPET: example2 -->
+ * Render an image submit:
+ * &lt;s:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/&gt;
+ * <!-- END SNIPPET: example2 -->
+ * </pre>
+ * <pre>
+ * <!-- START SNIPPET: example3 -->
+ * Render an button submit:
+ * &lt;s:submit type="button" value="%{'Submit'}" label="Submit the form"/&gt;
+ * <!-- END SNIPPET: example3 -->
+ * </pre>
+ *
+ * <!-- START SNIPPET: ajaxJavadoc -->
+ * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
+ * <ul>
+ *      <li>href</li>
+ *      <li>errorText</li>
+ *      <li>listenTopics</li>
+ *      <li>notifyTopics</li>
+ *      <li>executeScripts</li>
+ *      <li>loadingText</li>
+ *      <li>listenTopics</li>
+ *      <li>handler</li>
+ *      <li>formId</li>
+ *      <li>formFilter</li>
+ *      <li>targets</li>
+ *      <li>showErrorTransportText</li>
+ *      <li>targets</li>
+ *      <li>indicator</li>
+ * </ul>
+ * 'resultDivId' Deprecated. Use targets.</p>
+ * 'targets' is a list of element ids whose content will be updated with the
+ * text returned from request.<p/>
+ * 'errorText' is the text that will be displayed when there is an error making the request.<p/>
+ * 'onLoadJS' Deprecated. Use 'notifyTopics'.<p/>
+ * 'preInvokeJS' Deprecated. Use 'notifyTopics'.<p/>
+ * 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
+ * 'loadingText' is the text that will be displayed on the 'targets' elements while making the
+ * request.<p/>
+ * 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
+ * and dom node are passed as parameters).<p/>
+ * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
+ * in the request.<p/>
+ * 'formFilter' is the name of a function which will be used to filter the fields that will be
+ * seralized. This function takes as a parameter the element and returns true if the element
+ * should be included.<p/>
+ * 'listenTopics' comma separated list of topics names, that will trigger a request
+ * 'indicator' element to be shown while the request executing
+ * 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
+ * 'showLoadingText' show loading text on targets</p>
+ * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
+ * <ul>
+ *      <li>data: html or json object when type='load' or type='error'</li>
+ *      <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
+ *      <li>request: request javascript object, when type='load' or type='error'</li>
+ * </ul>
+ * <!-- END SNIPPET: ajaxJavadoc -->
+ *
+ * <!-- START SNIPPET: ajxExDescription1 -->
+ * Show the results in another div. If you want your results to be shown in
+ * a div, use the resultDivId where the id is the id of the div you want them
+ * shown in. This is an inner HTML approah. Your results get jammed into
+ * the div for you. Here is a sample of this approach:
+ * <!-- END SNIPPET: ajxExDescription1 -->
+ *
+ * <pre>
+ * <!-- START SNIPPET: ajxExample1 -->
+ * Remote form replacing another div:
+ * &lt;div id='two' style="border: 1px solid yellow;"&gt;Initial content&lt;/div&gt;
+ * &lt;s:form
+ *       id='theForm2'
+ *       cssStyle="border: 1px solid green;"
+ *       action='/AjaxRemoteForm.action'
+ *       method='post'
+ *       theme="ajax"&gt;
+ *
+ *   &lt;input type='text' name='data' value='Struts User' /&gt;
+ *   &lt;s:submit value="GO2" theme="ajax" resultDivId="two" /&gt;
+ *
+ * &lt;/s:form &gt;
+ * <!-- END SNIPPET: ajxExample1 -->
+ * </pre>
+ *
+ */
+@StrutsTag(name="submit", tldTagClass="org.apache.struts2.views.jsp.ui.SubmitTag", description="Render a submit button")
+@StrutsTagSkipInheritance
+public class Submit extends FormButton implements RemoteUICallBean {
+    
+    private static final Log LOG = LogFactory.getLog(Submit.class);
+    
+    final public static String TEMPLATE = "submit";
+
+    protected String href;
+    protected String errorText;
+    protected String executeScripts;
+    protected String loadingText;
+    protected String listenTopics;
+    protected String handler;
+    protected String formId;
+    protected String formFilter;
+    protected String src;
+    protected String notifyTopics;
+    protected String showErrorTransportText;
+    protected String indicator;
+    protected String showLoadingText;
+    //these two are called "preInvokeJS" and "onLoadJS" on the tld
+    //Names changed here to keep some consistency
+    protected String beforeLoading;
+    protected String afterLoading;
+
+    //this one is called "resultDivId" on the tld
+    protected String targets;
+
+    public Submit(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE;
+    }
+
+    public void evaluateParams() {
+        if ((key == null) && (value == null)) {
+            value = "Submit";
+        }
+
+        if (((key != null)) && (value == null)) {
+            this.value = "%{getText('"+key +"')}";
+        }
+
+        super.evaluateParams();
+    }
+
+    public void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if (href != null)
+            addParameter("href", findString(href));
+        if (errorText != null)
+            addParameter("errorText", findString(errorText));
+        if (loadingText != null)
+            addParameter("loadingText", findString(loadingText));
+        if (afterLoading != null)
+            addParameter("afterLoading", findString(afterLoading));
+        if (beforeLoading != null)
+            addParameter("beforeLoading", findString(beforeLoading));
+        if (executeScripts != null)
+            addParameter("executeScripts", findValue(executeScripts, Boolean.class));
+        if (listenTopics != null)
+            addParameter("listenTopics", findString(listenTopics));
+        if (notifyTopics != null)
+            addParameter("notifyTopics", findString(notifyTopics));
+        if (handler != null)
+            addParameter("handler", findString(handler));
+        if (formId != null)
+            addParameter("formId", findString(formId));
+        if (formFilter != null)
+            addParameter("formFilter", findString(formFilter));
+        if (src != null)
+            addParameter("src", findString(src));
+        if (indicator != null)
+            addParameter("indicator", findString(indicator));
+        if (targets != null)
+            addParameter("targets", findString(targets));
+        if (showLoadingText != null)
+            addParameter("showLoadingText", findString(showLoadingText));
+    }
+
+    /**
+     * Indicate whether the concrete button supports the type "image".
+     *
+     * @return <tt>true</tt> to indicate type image is supported.
+     */
+    protected boolean supportsImageType() {
+        return true;
+    }
+    
+    /**
+     * Overrides to be able to render body in a template rather than always before the template
+     */
+    public boolean end(Writer writer, String body) {
+        evaluateParams();
+        try {
+            addParameter("body", body);
+            
+            mergeTemplate(writer, buildTemplateName(template, getDefaultTemplate()));
+        } catch (Exception e) {
+            LOG.error("error when rendering", e);
+        }
+        finally {
+            popComponentStack();
+        }
+
+        return false;
+    }
+
+    @StrutsTagAttribute(description="Topic that will trigger the remote call")
+    public void setListenTopics(String listenTopics) {
+        this.listenTopics = listenTopics;
+    }
+
+    @StrutsTagAttribute(description="The theme to use for the element. <b>This tag will usually use the ajax theme.</b>")
+    public void setTheme(String theme) {
+        super.setTheme(theme);
+    }
+
+    @StrutsTagAttribute(description="The URL to call to obtain the content. Note: If used with ajax context, the value must be set as an url tag value.")
+    public void setHref(String href) {
+        this.href = href;
+    }
+
+    @StrutsTagAttribute(description="The text to display to the user if the is an error fetching the content")
+    public void setErrorText(String errorText) {
+        this.errorText = errorText;
+    }
+
+    @StrutsTagAttribute(name="onLoadJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
+    public void setAfterLoading(String afterLoading) {
+        this.afterLoading = afterLoading;
+    }
+
+
+    @StrutsTagAttribute(name="preInvokeJS", description="Deprecated. Use 'notifyTopics'. Javascript code execute before reload")
+    public void setBeforeLoading(String beforeLoading) {
+        this.beforeLoading = beforeLoading;
+    }
+
+    @StrutsTagAttribute(description="Javascript code in the fetched content will be executed", type="Boolean", defaultValue="false")
+    public void setExecuteScripts(String executeScripts) {
+        this.executeScripts = executeScripts;
+    }
+
+    @StrutsTagAttribute(description="Text to be shown while content is being fetched", defaultValue="Loading...")
+    public void setLoadingText(String loadingText) {
+        this.loadingText = loadingText;
+    }
+
+    @StrutsTagAttribute(description="Javascript function name that will make the request")
+    public void setHandler(String handler) {
+        this.handler = handler;
+    }
+
+    @StrutsTagAttribute(description="Function name used to filter the fields of the form.")
+    public void setFormFilter(String formFilter) {
+        this.formFilter = formFilter;
+    }
+
+    @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
+    public void setFormId(String formId) {
+        this.formId = formId;
+    }
+
+    @StrutsTagAttribute(description="Supply an image src for <i>image</i> type submit button. Will have no effect for types <i>input</i> and <i>button</i>.")
+    public void setSrc(String src) {
+        this.src = src;
+    }
+
+    @StrutsTagAttribute(description="Comma delimited list of ids of the elements whose content will be updated")
+    public void setTargets(String targets) {
+        this.targets = targets;
+    }
+
+
+    @StrutsTagAttribute(description="Topics that will published when the remote call completes")
+    public void setNotifyTopics(String notifyTopics) {
+        this.notifyTopics = notifyTopics;
+    }
+
+
+    @StrutsTagAttribute(description="Set whether errors will be shown or not", type="Boolean", defaultValue="true")
+    public void setShowErrorTransportText(String showErrorTransportText) {
+        this.showErrorTransportText = showErrorTransportText;
+    }
+
+
+    @StrutsTagAttribute(description="Set indicator")
+    public void setIndicator(String indicator) {
+        this.indicator = indicator;
+    }
+
+    @StrutsTagAttribute(description="Show loading text on targets", type="Boolean", defaultValue="true")
+    public void setShowLoadingText(String showLoadingText) {
+        this.showLoadingText = showLoadingText;
+    }
+}

Added: struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/TabbedPanel.java
URL: http://svn.apache.org/viewvc/struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/TabbedPanel.java?view=auto&rev=514083
==============================================================================
--- struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/TabbedPanel.java (added)
+++ struts/struts2/trunk/plugins/dojo/src/main/java/org/apache/struts2/components/TabbedPanel.java Fri Mar  2 21:48:54 2007
@@ -0,0 +1,137 @@
+/*
+ * $Id: TabbedPanel.java 508575 2007-02-16 20:46:49Z musachy $
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.components;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.views.annotations.StrutsTag;
+import org.apache.struts2.views.annotations.StrutsTagAttribute;
+import org.apache.struts2.views.annotations.StrutsTagSkipInheritance;
+
+import com.opensymphony.xwork2.util.ValueStack;
+
+/**
+ * <!-- START SNIPPET: javadoc -->
+ * The tabbedpanel widget is primarily an AJAX component, where each tab can either be local content or remote
+ * content (refreshed each time the user selects that tab).</p>
+ * <!-- END SNIPPET: javadoc -->
+ *
+ * <p/> <b>Examples</b>
+ * <p/>
+ * <!-- START SNIPPET: exdesc -->
+ * The following is an example of a tabbedpanel and panel tag utilizing local and remote content.<p/>
+ * <!-- END SNIPPET: exdesc -->
+ * <pre>
+ * <!-- START SNIPPET: example -->
+ * &lt;s:tabbedPanel id=&quot;test&quot; &gt;
+ *    &lt;s:div id=&quot;one&quot; label=&quot;one&quot; theme=&quot;ajax&quot; labelposition=&quot;top&quot; &gt;
+ *        This is the first pane&lt;br/&gt;
+ *        &lt;s:form&gt;
+ *            &lt;s:textfield name=&quot;tt&quot; label=&quot;Test Text&quot;/&gt;  &lt;br/&gt;
+ *            &lt;s:textfield name=&quot;tt2&quot; label=&quot;Test Text2&quot;/&gt;
+ *        &lt;/s:form&gt;
+ *    &lt;/s:div&gt;
+ *    &lt;s:div id=&quot;three&quot; label=&quot;remote&quot; theme=&quot;ajax&quot; href=&quot;/AjaxTest.action&quot; &gt;
+ *        This is the remote tab
+ *    &lt;/s:div&gt;
+ * &lt;/s:tabbedPanel&gt;
+ * <!-- END SNIPPET: example -->
+ * </pre>
+ *
+ */
+@StrutsTag(name="tabbedPanel", tldTagClass="org.apache.struts2.views.jsp.ui.TabbedPanelTag", description="Render a tabbedPanel widget.")
+@StrutsTagSkipInheritance
+public class TabbedPanel extends ClosingUIBean {
+    public static final String TEMPLATE = "tabbedpanel";
+    public static final String TEMPLATE_CLOSE = "tabbedpanel-close";
+    final private static String COMPONENT_NAME = TabbedPanel.class.getName();
+
+    protected String selectedTab;
+    protected String closeButton;
+    protected String doLayout ;
+    protected String templateCssPath;
+
+    public TabbedPanel(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
+        super(stack, request, response);
+    }
+
+
+    protected void evaluateExtraParams() {
+        super.evaluateExtraParams();
+
+        if(selectedTab != null)
+            addParameter("selectedTab", findString(selectedTab));
+        if(closeButton != null)
+            addParameter("closeButton", findString(closeButton));
+        addParameter("doLayout", doLayout != null ? findValue(doLayout, Boolean.class) : Boolean.FALSE);
+        if(labelPosition != null) {
+            //dojo has some weird name for label positions
+            if(labelPosition.equalsIgnoreCase("left"))
+               labelPosition = "left-h";
+            if(labelPosition.equalsIgnoreCase("right"))
+                labelPosition = "right-h";
+            addParameter("labelPosition", null);
+            addParameter("labelPosition", labelPosition);
+        }
+        if(templateCssPath != null)
+            addParameter("templateCssPath", findString(templateCssPath));
+    }
+
+    public String getDefaultOpenTemplate() {
+        return TEMPLATE;
+    }
+
+    protected String getDefaultTemplate() {
+        return TEMPLATE_CLOSE;
+    }
+
+    public String getComponentName() {
+        return COMPONENT_NAME;
+    }
+
+    @StrutsTagAttribute(description="The id to assign to the component.", required=true)
+    public void setId(String id) {
+        // This is required to override tld generation attributes to required=true
+        super.setId(id);
+    }
+
+
+    @StrutsTagAttribute(description=" The id of the tab that will be selected by default")
+    public void setSelectedTab(String selectedTab) {
+      this.selectedTab = selectedTab;
+    }
+
+    @StrutsTagAttribute(description="Where the close button will be placed, possible values are 'tab' and 'pane'")
+    public void setCloseButton(String closeButton) {
+        this.closeButton = closeButton;
+    }
+
+    @StrutsTagAttribute(description="If doLayout is false, the tab container's height equals the height of the currently selected tab", type="Boolean", defaultValue="false")
+    public void setDoLayout(String doLayout) {
+        this.doLayout = doLayout;
+    }
+
+    @StrutsTagAttribute(description="Template css path")
+    public void setTemplateCssPath(String templateCssPath) {
+        this.templateCssPath = templateCssPath;
+    }
+}