diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/AbstractRemoteBean.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/AbstractRemoteBean.java index e6f442bab..f31fd1af6 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/AbstractRemoteBean.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/AbstractRemoteBean.java @@ -1,246 +1,256 @@ -/* - * $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.dojo.components; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.components.ClosingUIBean; -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. - */ -public abstract class AbstractRemoteBean extends ClosingUIBean implements RemoteBean { - - 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 notifyTopics; - protected String showErrorTransportText; - protected String indicator; - protected String showLoadingText; - protected String beforeNotifyTopics; - protected String afterNotifyTopics; - protected String errorNotifyTopics; - protected String highlightColor; - protected String highlightDuration; - protected String separateScripts; - protected String transport; - protected String parseContent; - - public AbstractRemoteBean(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 (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)); - if (beforeNotifyTopics != null) - addParameter("beforeNotifyTopics", findString(beforeNotifyTopics)); - if (afterNotifyTopics != null) - addParameter("afterNotifyTopics", findString(afterNotifyTopics)); - if (errorNotifyTopics != null) - addParameter("errorNotifyTopics", findString(errorNotifyTopics)); - if (highlightColor != null) - addParameter("highlightColor", findString(highlightColor)); - if (highlightDuration != null) - addParameter("highlightDuration", findString(highlightDuration)); - if (separateScripts != null) - addParameter("separateScripts", findValue(separateScripts, Boolean.class)); - if (transport != null) - addParameter("transport", findString(transport)); - if (parseContent != null) - addParameter("parseContent", findValue(parseContent, Boolean.class)); - else - addParameter("parseContent", true); - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - @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; - } - - @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="Comma delimmited list of topics that will published before and after the request, and on errors") - 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="false") - public void setShowLoadingText(String showLoadingText) { - this.showLoadingText = showLoadingText; - } - - @StrutsTagAttribute(description="The css class to use for element") - public void setCssClass(String cssClass) { - super.setCssClass(cssClass); - } - - @StrutsTagAttribute(description="The css style to use for element") - public void setCssStyle(String cssStyle) { - super.setCssStyle(cssStyle); - } - - @StrutsTagAttribute(description="The id to use for the element") - public void setId(String id) { - super.setId(id); - } - - @StrutsTagAttribute(description="The name to set for element") - public void setName(String name) { - super.setName(name); - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)") - public void setAfterNotifyTopics(String afterNotifyTopics) { - this.afterNotifyTopics = afterNotifyTopics; - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request") - public void setBeforeNotifyTopics(String beforeNotifyTopics) { - this.beforeNotifyTopics = beforeNotifyTopics; - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)") - public void setErrorNotifyTopics(String errorNotifyTopics) { - this.errorNotifyTopics = errorNotifyTopics; - } - - @StrutsTagAttribute(description = "Color used to perform a highlight effect on the elements specified in the 'targets' attribute", - defaultValue = "none") - public void setHighlightColor(String highlightColor) { - this.highlightColor = highlightColor; - } - - @StrutsTagAttribute(description = "Duration of highlight effect in milliseconds. Only valid if 'highlightColor' attribute is set", - defaultValue = "2000", type="Integer") - public void setHighlightDuration(String highlightDuration) { - this.highlightDuration = highlightDuration; - } - - @StrutsTagAttribute(description="Run scripts in a separate scope, unique for each tag", defaultValue="true") - public void setSeparateScripts(String separateScripts) { - this.separateScripts = separateScripts; - } - - @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport") - public void setTransport(String transport) { - this.transport = transport; - } - - @StrutsTagAttribute(description="Parse returned HTML for Dojo widgets", defaultValue="true", type="Boolean") - public void setParseContent(String parseContent) { - this.parseContent = parseContent; - } -} +/* + * $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.dojo.components; + +import java.util.Random; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts2.components.ClosingUIBean; +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. + */ +public abstract class AbstractRemoteBean extends ClosingUIBean implements RemoteBean { + + 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 notifyTopics; + protected String showErrorTransportText; + protected String indicator; + protected String showLoadingText; + protected String beforeNotifyTopics; + protected String afterNotifyTopics; + protected String errorNotifyTopics; + protected String highlightColor; + protected String highlightDuration; + protected String separateScripts; + protected String transport; + protected String parseContent; + + public AbstractRemoteBean(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 (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)); + if (beforeNotifyTopics != null) + addParameter("beforeNotifyTopics", findString(beforeNotifyTopics)); + if (afterNotifyTopics != null) + addParameter("afterNotifyTopics", findString(afterNotifyTopics)); + if (errorNotifyTopics != null) + addParameter("errorNotifyTopics", findString(errorNotifyTopics)); + if (highlightColor != null) + addParameter("highlightColor", findString(highlightColor)); + if (highlightDuration != null) + addParameter("highlightDuration", findString(highlightDuration)); + if (separateScripts != null) + addParameter("separateScripts", findValue(separateScripts, Boolean.class)); + if (transport != null) + addParameter("transport", findString(transport)); + if (parseContent != null) + addParameter("parseContent", findValue(parseContent, Boolean.class)); + else + addParameter("parseContent", true); + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + @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; + } + + @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="Comma delimmited list of topics that will published before and after the request, and on errors") + 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="false") + public void setShowLoadingText(String showLoadingText) { + this.showLoadingText = showLoadingText; + } + + @StrutsTagAttribute(description="The css class to use for element") + public void setCssClass(String cssClass) { + super.setCssClass(cssClass); + } + + @StrutsTagAttribute(description="The css style to use for element") + public void setCssStyle(String cssStyle) { + super.setCssStyle(cssStyle); + } + + @StrutsTagAttribute(description="The id to use for the element") + public void setId(String id) { + super.setId(id); + } + + @StrutsTagAttribute(description="The name to set for element") + public void setName(String name) { + super.setName(name); + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)") + public void setAfterNotifyTopics(String afterNotifyTopics) { + this.afterNotifyTopics = afterNotifyTopics; + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request") + public void setBeforeNotifyTopics(String beforeNotifyTopics) { + this.beforeNotifyTopics = beforeNotifyTopics; + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)") + public void setErrorNotifyTopics(String errorNotifyTopics) { + this.errorNotifyTopics = errorNotifyTopics; + } + + @StrutsTagAttribute(description = "Color used to perform a highlight effect on the elements specified in the 'targets' attribute", + defaultValue = "none") + public void setHighlightColor(String highlightColor) { + this.highlightColor = highlightColor; + } + + @StrutsTagAttribute(description = "Duration of highlight effect in milliseconds. Only valid if 'highlightColor' attribute is set", + defaultValue = "2000", type="Integer") + public void setHighlightDuration(String highlightDuration) { + this.highlightDuration = highlightDuration; + } + + @StrutsTagAttribute(description="Run scripts in a separate scope, unique for each tag", defaultValue="true") + public void setSeparateScripts(String separateScripts) { + this.separateScripts = separateScripts; + } + + @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport") + public void setTransport(String transport) { + this.transport = transport; + } + + @StrutsTagAttribute(description="Parse returned HTML for Dojo widgets", defaultValue="true", type="Boolean") + public void setParseContent(String parseContent) { + this.parseContent = parseContent; + } +} diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Autocompleter.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Autocompleter.java index f6101333c..752927fbf 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Autocompleter.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Autocompleter.java @@ -1,527 +1,537 @@ -/* - * $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.dojo.components; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.components.ComboBox; -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; - -/** - * - *

The autocomplete tag is a combobox that can autocomplete text entered on the input box. If an action - * is used to populate the autocompleter, the output of the action must be a well formed JSON string.

- *

The autocompleter follows this rule to find its datasource:

- *

1. If the response is an array, assume that it contains 2-dimension array elements, like: - *

- * [
- *      ["Alabama", "AL"],
- *      ["Alaska", "AK"]
- * ]
- * 
- *

2. If a value is specified in the "dataFieldName" attribute, and the response has a field with that - * name, assume that's the datasource, which can be an array of 2-dimension array elements, or a map, - * like (assuming dataFieldName="state"):

- *
- * {
- *      "state" : [
- *           ["Alabama","AL"],
- *           ["Alaska","AK"]
- *      ]
- * }     
- * 
- * or
- * 
- * {
- *      "state" : {
- *            "Alabama" : "AL",
- *            "Alaska" : "AK"
- *      }
- * }
- * 
- * - *

3. If there is a field that starts with the value specified on the "name" attribute, assume - * that's the datasource, like (assuming name="state"):

- *
- * {
- *      "states" : [
- *           ["Alabama","AL"],
- *           ["Alaska","AK"]
- *      ]
- * }
- * 
- *

4. Use first array that is found, like:

- *

- * {
- *      "anything" : [
- *            ["Alabama", "AL"],
- *            ["Alaska", "AK"]
- *     ]       
- * }
- * 

5. If the response is a map, use it (recommended as it is the easiest one to generate): - *

- * {
- *      "Alabama" : "AL",
- *      "Alaska" : "AK"
- * }
- * 
- * - *

Examples

- * - *

Autocompleter that gets its list from an action:

- *
- * <sx:autocompleter name="autocompleter1" href="%{jsonList}"/>
- * 
- * - * - * - *

Autocompleter that uses a list:

- *
- * <s:autocompleter name="test"  list="{'apple','banana','grape','pear'}" autoComplete="false"/>
- * 
- * - * - * - *

Autocompleter that reloads its content everytime the text changes (and the length of the text is greater than 3):

- *
- * <sx:autocompleter name="mvc" href="%{jsonList}" loadOnTextChange="true" loadMinimumCount="3"/>
- * 
- * The text entered on the autocompleter is passed as a parameter to the url specified in "href", like (text is "struts"):
- *  
- * http://host/example/myaction.do?mvc=struts
- * 
- * - * - * - *

Linking two autocompleters:

- *
- * <form id="selectForm">
- *      <sx:autocompleter  name="select" list="{'fruits','colors'}"  valueNotifyTopics="/changed" />
- * </form>  
- * <sx:autocompleter  href="%{jsonList}" formId="selectForm" listenTopics="/changed"/>
- * 
- * - * - * - *

Set/Get selected values using JavaScript

- *
- * <sx:autocompleter  href="%{jsonList}" id="auto"/>
- * <script type="text/javascript">
- *   function getValues() {
- *      var autoCompleter = dojo.widget.byId("auto");
- *      
- *      //key (in the states example above, "AL")
- *      var key = autoCompleter.getSelectedKey();
- *      alert(key);
- *      
- *      //value (in the states example above, "Alabama")
- *      var value = autoCompleter.getSelectedValue();
- *      alert(value);
- *      
- *      //text currently on the textbox (anything the user typed)
- *      var text = autoCompleter.getText();
- *      alert(text);
- *   }
- * 
- *   function setValues() {
- *      var autoCompleter = dojo.widget.byId("auto");
- *      
- *      //key (key will be set to "AL" and value to "Alabama")
- *      autoCompleter.setSelectedKey("AL");
- *      
- *      //value (key will be set to "AL" and value to "Alabama")
- *      autoCompleter.setAllValues("AL", "Alabama");
- *   }
- * </script>
- * 
- * - * - * - *

Using beforeNotifyTopics:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/before", function(event, widget){
- *     alert('inside a topic event. before request');
- *     //event: set event.cancel = true, to cancel request
- *     //widget: widget that published the topic
- * });
- * </script>         
- * 
- * <sx:autocompleter beforeNotifyTopics="/before" href="%{#ajaxTest} />
- * 
- * - * - * - *

Using afterNotifyTopics:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/after", function(data, request, widget){
- *     alert('inside a topic event. after request');
- *     //data : JavaScript object from parsing response
- *     //request: XMLHttpRequest object
- *     //widget: widget that published the topic
- * });
- * </script>        
- * 
- * <sx:autocompleter afterNotifyTopics="/after" href="%{#ajaxTest}" />
- * 
- * - * - * - *

Using errorNotifyTopics:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/error", function(error, request, widget){
- *     alert('inside a topic event. on error');
- *     //error : error object (error.message has the error message)
- *     //request: XMLHttpRequest object
- *     //widget: widget that published the topic
- * });
- * </script>
- * 
- * <sx:autocompleter errorNotifyTopics="/error" href="%{#ajaxTest}" />
- * 
- * - * - * - *

Using valueNotifyTopics and indicator:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/value", function(value, key, text, widget){
- *     alert('inside a topic event. after value changed');
- *     //value : selected value (like "Florida" in example above)
- *     //key: selected key (like "FL" in example above)
- *     //text: text typed into textbox
- *     //widget: widget that published the topic
- * });
- * </script>   
- * 
- * 
- */
-@StrutsTag(name="autocompleter", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
-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;
-    protected String beforeNotifyTopics;
-    protected String afterNotifyTopics;
-    protected String errorNotifyTopics;
-    protected String valueNotifyTopics;
-    protected String resultsLimit;
-    protected String transport;
-    protected String preload;
-    
-    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));
-        }
-        if (transport != null)
-            addParameter("transport", findString(transport));
-        if (preload != null)
-            addParameter("preload", findValue(preload, Boolean.class));
-        
-        String keyNameExpr = "%{" + keyName + "}";
-        addParameter("key", findString(keyNameExpr));
-        
-        if (beforeNotifyTopics != null)
-            addParameter("beforeNotifyTopics", findString(beforeNotifyTopics));
-        if (afterNotifyTopics != null)
-            addParameter("afterNotifyTopics", findString(afterNotifyTopics));
-        if (errorNotifyTopics != null)
-            addParameter("errorNotifyTopics", findString(errorNotifyTopics));
-        if (valueNotifyTopics != null)
-            addParameter("valueNotifyTopics", findString(valueNotifyTopics));
-        if (resultsLimit != null)
-            addParameter("searchLimit", findString(resultsLimit));
-    }
-
-    @Override
-    @StrutsTagSkipInheritance
-    public void setTheme(String theme) {
-        super.setTheme(theme);
-    }
-    
-    @Override
-    public String getTheme() {
-        return "ajax";
-    }
-    
-    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;
-    }
-    
-    @StrutsTagAttribute(description="The css class to use for element")
-    public void setCssClass(String cssClass) {
-        super.setCssClass(cssClass);
-    }
-
-    @StrutsTagAttribute(description="The css style to use for element")
-    public void setCssStyle(String cssStyle) {
-        super.setCssStyle(cssStyle);
-    }
-
-    @StrutsTagAttribute(description="The id to use for the element")
-    public void setId(String id) {
-        super.setId(id);
-    }
-
-    @StrutsTagAttribute(description="The name to set for element")
-    public void setName(String name) {
-        super.setName(name);
-    }
-
-    @StrutsTagAttribute(description="Preset the value of input element")
-    public void setValue(String arg0) {
-        super.setValue(arg0);
-    }
-    
-    @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)")
-    public void setAfterNotifyTopics(String afterNotifyTopics) {
-        this.afterNotifyTopics = afterNotifyTopics;
-    }
-
-    @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request")
-    public void setBeforeNotifyTopics(String beforeNotifyTopics) {
-        this.beforeNotifyTopics = beforeNotifyTopics;
-    }
-
-    @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)")
-    public void setErrorNotifyTopics(String errorNotifyTopics) {
-        this.errorNotifyTopics = errorNotifyTopics;
-    }
-
-    @StrutsTagAttribute(description="Comma delimmited list of topics that will published when a value is selected")
-    public void setValueNotifyTopics(String valueNotifyTopics) {
-        this.valueNotifyTopics = valueNotifyTopics;
-    }
-    
-    @StrutsTagAttribute(description="Limit how many results are shown as autocompletion options, set to -1 for unlimited results", defaultValue="30")
-    public void setResultsLimit(String resultsLimit) {
-        this.resultsLimit = resultsLimit;
-    }
-    
-    @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport")
-    public void setTransport(String transport) {
-        this.transport = transport;
-    }
-    
-    @StrutsTagAttribute(description="Load options when page is loaded", type="Boolean", defaultValue="true")
-    public void setPreload(String preload) {
-        this.preload = preload;
-    }
-}
+/*
+ * $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.dojo.components;
+
+import java.util.Random;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.struts2.components.ComboBox;
+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;
+
+/**
+ * 
+ * 

The autocomplete tag is a combobox that can autocomplete text entered on the input box. If an action + * is used to populate the autocompleter, the output of the action must be a well formed JSON string.

+ *

The autocompleter follows this rule to find its datasource:

+ *

1. If the response is an array, assume that it contains 2-dimension array elements, like: + *

+ * [
+ *      ["Alabama", "AL"],
+ *      ["Alaska", "AK"]
+ * ]
+ * 
+ *

2. If a value is specified in the "dataFieldName" attribute, and the response has a field with that + * name, assume that's the datasource, which can be an array of 2-dimension array elements, or a map, + * like (assuming dataFieldName="state"):

+ *
+ * {
+ *      "state" : [
+ *           ["Alabama","AL"],
+ *           ["Alaska","AK"]
+ *      ]
+ * }     
+ * 
+ * or
+ * 
+ * {
+ *      "state" : {
+ *            "Alabama" : "AL",
+ *            "Alaska" : "AK"
+ *      }
+ * }
+ * 
+ *
+ *

3. If there is a field that starts with the value specified on the "name" attribute, assume + * that's the datasource, like (assuming name="state"):

+ *
+ * {
+ *      "states" : [
+ *           ["Alabama","AL"],
+ *           ["Alaska","AK"]
+ *      ]
+ * }
+ * 
+ *

4. Use first array that is found, like:

+ *

+ * {
+ *      "anything" : [
+ *            ["Alabama", "AL"],
+ *            ["Alaska", "AK"]
+ *     ]       
+ * }
+ * 

5. If the response is a map, use it (recommended as it is the easiest one to generate): + *

+ * {
+ *      "Alabama" : "AL",
+ *      "Alaska" : "AK"
+ * }
+ * 
+ * + *

Examples

+ * + *

Autocompleter that gets its list from an action:

+ *
+ * <sx:autocompleter name="autocompleter1" href="%{jsonList}"/>
+ * 
+ * + * + * + *

Autocompleter that uses a list:

+ *
+ * <s:autocompleter name="test"  list="{'apple','banana','grape','pear'}" autoComplete="false"/>
+ * 
+ * + * + * + *

Autocompleter that reloads its content everytime the text changes (and the length of the text is greater than 3):

+ *
+ * <sx:autocompleter name="mvc" href="%{jsonList}" loadOnTextChange="true" loadMinimumCount="3"/>
+ * 
+ * The text entered on the autocompleter is passed as a parameter to the url specified in "href", like (text is "struts"):
+ *  
+ * http://host/example/myaction.do?mvc=struts
+ * 
+ * + * + * + *

Linking two autocompleters:

+ *
+ * <form id="selectForm">
+ *      <sx:autocompleter  name="select" list="{'fruits','colors'}"  valueNotifyTopics="/changed" />
+ * </form>  
+ * <sx:autocompleter  href="%{jsonList}" formId="selectForm" listenTopics="/changed"/>
+ * 
+ * + * + * + *

Set/Get selected values using JavaScript

+ *
+ * <sx:autocompleter  href="%{jsonList}" id="auto"/>
+ * <script type="text/javascript">
+ *   function getValues() {
+ *      var autoCompleter = dojo.widget.byId("auto");
+ *      
+ *      //key (in the states example above, "AL")
+ *      var key = autoCompleter.getSelectedKey();
+ *      alert(key);
+ *      
+ *      //value (in the states example above, "Alabama")
+ *      var value = autoCompleter.getSelectedValue();
+ *      alert(value);
+ *      
+ *      //text currently on the textbox (anything the user typed)
+ *      var text = autoCompleter.getText();
+ *      alert(text);
+ *   }
+ * 
+ *   function setValues() {
+ *      var autoCompleter = dojo.widget.byId("auto");
+ *      
+ *      //key (key will be set to "AL" and value to "Alabama")
+ *      autoCompleter.setSelectedKey("AL");
+ *      
+ *      //value (key will be set to "AL" and value to "Alabama")
+ *      autoCompleter.setAllValues("AL", "Alabama");
+ *   }
+ * </script>
+ * 
+ * + * + * + *

Using beforeNotifyTopics:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/before", function(event, widget){
+ *     alert('inside a topic event. before request');
+ *     //event: set event.cancel = true, to cancel request
+ *     //widget: widget that published the topic
+ * });
+ * </script>         
+ * 
+ * <sx:autocompleter beforeNotifyTopics="/before" href="%{#ajaxTest} />
+ * 
+ * + * + * + *

Using afterNotifyTopics:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/after", function(data, request, widget){
+ *     alert('inside a topic event. after request');
+ *     //data : JavaScript object from parsing response
+ *     //request: XMLHttpRequest object
+ *     //widget: widget that published the topic
+ * });
+ * </script>        
+ * 
+ * <sx:autocompleter afterNotifyTopics="/after" href="%{#ajaxTest}" />
+ * 
+ * + * + * + *

Using errorNotifyTopics:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/error", function(error, request, widget){
+ *     alert('inside a topic event. on error');
+ *     //error : error object (error.message has the error message)
+ *     //request: XMLHttpRequest object
+ *     //widget: widget that published the topic
+ * });
+ * </script>
+ * 
+ * <sx:autocompleter errorNotifyTopics="/error" href="%{#ajaxTest}" />
+ * 
+ * + * + * + *

Using valueNotifyTopics and indicator:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/value", function(value, key, text, widget){
+ *     alert('inside a topic event. after value changed');
+ *     //value : selected value (like "Florida" in example above)
+ *     //key: selected key (like "FL" in example above)
+ *     //text: text typed into textbox
+ *     //widget: widget that published the topic
+ * });
+ * </script>   
+ * 
+ * 
+ */
+@StrutsTag(name="autocompleter", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
+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;
+    protected String beforeNotifyTopics;
+    protected String afterNotifyTopics;
+    protected String errorNotifyTopics;
+    protected String valueNotifyTopics;
+    protected String resultsLimit;
+    protected String transport;
+    protected String preload;
+    
+    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));
+        }
+        if (transport != null)
+            addParameter("transport", findString(transport));
+        if (preload != null)
+            addParameter("preload", findValue(preload, Boolean.class));
+        
+        String keyNameExpr = "%{" + keyName + "}";
+        addParameter("key", findString(keyNameExpr));
+        
+        if (beforeNotifyTopics != null)
+            addParameter("beforeNotifyTopics", findString(beforeNotifyTopics));
+        if (afterNotifyTopics != null)
+            addParameter("afterNotifyTopics", findString(afterNotifyTopics));
+        if (errorNotifyTopics != null)
+            addParameter("errorNotifyTopics", findString(errorNotifyTopics));
+        if (valueNotifyTopics != null)
+            addParameter("valueNotifyTopics", findString(valueNotifyTopics));
+        if (resultsLimit != null)
+            addParameter("searchLimit", findString(resultsLimit));
+        
+        boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT);
+        addParameter("pushId", generateId);
+        if ((this.id == null || this.id.length() == 0) && generateId) {
+            Random random = new Random();
+            this.id = "widget_" + Math.abs(random.nextInt());
+            addParameter("id", this.id);
+        }
+    }
+
+    @Override
+    @StrutsTagSkipInheritance
+    public void setTheme(String theme) {
+        super.setTheme(theme);
+    }
+    
+    @Override
+    public String getTheme() {
+        return "ajax";
+    }
+    
+    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;
+    }
+    
+    @StrutsTagAttribute(description="The css class to use for element")
+    public void setCssClass(String cssClass) {
+        super.setCssClass(cssClass);
+    }
+
+    @StrutsTagAttribute(description="The css style to use for element")
+    public void setCssStyle(String cssStyle) {
+        super.setCssStyle(cssStyle);
+    }
+
+    @StrutsTagAttribute(description="The id to use for the element")
+    public void setId(String id) {
+        super.setId(id);
+    }
+
+    @StrutsTagAttribute(description="The name to set for element")
+    public void setName(String name) {
+        super.setName(name);
+    }
+
+    @StrutsTagAttribute(description="Preset the value of input element")
+    public void setValue(String arg0) {
+        super.setValue(arg0);
+    }
+    
+    @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)")
+    public void setAfterNotifyTopics(String afterNotifyTopics) {
+        this.afterNotifyTopics = afterNotifyTopics;
+    }
+
+    @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request")
+    public void setBeforeNotifyTopics(String beforeNotifyTopics) {
+        this.beforeNotifyTopics = beforeNotifyTopics;
+    }
+
+    @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)")
+    public void setErrorNotifyTopics(String errorNotifyTopics) {
+        this.errorNotifyTopics = errorNotifyTopics;
+    }
+
+    @StrutsTagAttribute(description="Comma delimmited list of topics that will published when a value is selected")
+    public void setValueNotifyTopics(String valueNotifyTopics) {
+        this.valueNotifyTopics = valueNotifyTopics;
+    }
+    
+    @StrutsTagAttribute(description="Limit how many results are shown as autocompletion options, set to -1 for unlimited results", defaultValue="30")
+    public void setResultsLimit(String resultsLimit) {
+        this.resultsLimit = resultsLimit;
+    }
+    
+    @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport")
+    public void setTransport(String transport) {
+        this.transport = transport;
+    }
+    
+    @StrutsTagAttribute(description="Load options when page is loaded", type="Boolean", defaultValue="true")
+    public void setPreload(String preload) {
+        this.preload = preload;
+    }
+}
diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/DateTimePicker.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/DateTimePicker.java
index 1f6dce3fd..199a7e99c 100644
--- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/DateTimePicker.java
+++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/DateTimePicker.java
@@ -1,420 +1,429 @@
-/*
- * $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.dojo.components;
-
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-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.components.UIBean;
-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;
-
-/**
- * 
- * 

- * Renders a date/time picker in a dropdown container. - *

- *

- * A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month, - * and/or year. - *

- * - *

- * 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.

- *

- * - * Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):- - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
FormatDescription
dDay of the month
DDay of year
MMonth - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.
yYear
hHour [1-12].
HHour [0-23].
mMinute. Use one or two for zero padding.
sSecond. Use one or two for zero padding.
- * - *

- * The value sent to the server is a locale-independent value, in a hidden field as defined - * by the name attribute. The value will be formatted conforming to RFC3 339 - * (yyyy-MM-dd'T'HH:mm:ss) - *

- *

- * The following formats(in order) will be used to parse the values of the attributes 'value', - * 'startDate' and 'endDate': - *

- *
    - *
  • SimpleDateFormat built using RFC 3339 (yyyy-MM-dd'T'HH:mm:ss) - *
  • SimpleDateFormat.getTimeInstance(DateFormat.SHORT) - *
  • SimpleDateFormat.getDateInstance(DateFormat.SHORT) - *
  • SimpleDateFormat.getDateInstance(DateFormat.MEDIUM) - *
  • SimpleDateFormat.getDateInstance(DateFormat.FULL) - *
  • SimpleDateFormat.getDateInstance(DateFormat.LONG) - *
  • SimpleDateFormat built using the value of the 'displayFormat' attribute(if any) - *
- * - * - * Examples - * - *
- * 
- *
- * Example 1:
- *     <sx:datetimepicker name="order.date" label="Order Date" />
- * Example 2:
- *     <sx:datetimepicker name="delivery.date" label="Delivery Date" displayFormat="yyyy-MM-dd"  />
- * Example 3:   
- *      <sx:datetimepicker name="delivery.date" label="Delivery Date" value="%{date}"  />
- * Example 4:    
- *      <sx:datetimepicker name="delivery.date" label="Delivery Date" value="%{'2007-01-01'}"  />
- * Example 5:           
- *      <sx:datetimepicker name="order.date" label="Order Date" value="%{'today'}"/>
- * 
- * 
- * - * - *

Getting and getting the datetimepicker value, from JavaScript

- *
- * <sx:datetimepicker id="picker" label="Order Date" />
- * <script type="text/javascript">
- *   function setValue() {
- *      var picker = dojo.widget.byId("picker");
- *      
- *      //string value
- *      picker.setValue('2007-01-01');
- *      
- *      //Date value
- *      picker.setValue(new Date());
- *   }
- *   
- *   function showValue() {
- *      var picker = dojo.widget.byId("picker");
- *      
- *      //string value
- *      var stringValue = picker.getValue();
- *      alert(stringValue);
- *      
- *      //date value
- *      var dateValue = picker.getDate();
- *      alert(dateValue);
- *   }
- * </script>
- * 
- * - * - * - *

Publish topic when value changes

- *
- * <sx:datetimepicker id="picker" label="Order Date" valueNotifyTopics="/value"/>
- * 
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/value", function(textEntered, date, widget){
- *     alert('value changed');
- *     //textEntered: String enetered in the textbox
- *     //date: JavaScript Date object with the value selected
- *     //widet: widget that published the topic 
- * });
- * </script>  
- * 
- * - */ -@StrutsTag(name="datetimepicker", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.DateTimePickerTag", description="Render datetimepicker") -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; - protected String valueNotifyTopics; - - public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { - super(stack, request, response); - } - - protected String getDefaultTemplate() { - return TEMPLATE; - } - - public void evaluateParams() { - super.evaluateParams(); - - if(displayFormat != null) - addParameter("displayFormat", findString(displayFormat)); - if(displayWeeks != null) - addParameter("displayWeeks", findString(displayWeeks)); - if(adjustWeeks != null) - addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class)); - if(startDate != null) - addParameter("startDate", format(findValue(startDate))); - if(endDate != null) - addParameter("endDate", format(findValue(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", format(findValue(value))); - - if(iconPath != null) - addParameter("iconPath", findString(iconPath)); - if(formatLength != null) - addParameter("formatLength", findString(formatLength)); - 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)); - if(valueNotifyTopics != null) - addParameter("valueNotifyTopics", findString(valueNotifyTopics)); - - // format the value to RFC 3399 - if(parameters.containsKey("value")) { - parameters.put("nameValue", parameters.get("value")); - } else { - if(name != null) { - addParameter("nameValue", format(findValue(name))); - } - } - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - @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; - } - - @StrutsTagAttribute(description="Preset the value of input element") - public void setValue(String arg0) { - super.setValue(arg0); - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published when a value is selected") - public void setValueNotifyTopics(String valueNotifyTopics) { - this.valueNotifyTopics = valueNotifyTopics; - } - - private String format(Object obj) { - if(obj == null) - return null; - - if(obj instanceof Date) { - return RFC3339_FORMAT.format((Date) obj); - } else if(obj instanceof Calendar) { - return RFC3339_FORMAT.format(((Calendar) obj).getTime()); - } - else { - // try to parse a date - String dateStr = obj.toString(); - if(dateStr.equalsIgnoreCase("today")) - return RFC3339_FORMAT.format(new Date()); - - - Date date = null; - //formats used to parse the date - List formats = new ArrayList(); - formats.add(RFC3339_FORMAT); - formats.add(SimpleDateFormat.getTimeInstance(DateFormat.SHORT)); - formats.add(SimpleDateFormat.getDateInstance(DateFormat.SHORT)); - formats.add(SimpleDateFormat.getDateInstance(DateFormat.MEDIUM)); - formats.add(SimpleDateFormat.getDateInstance(DateFormat.FULL)); - formats.add(SimpleDateFormat.getDateInstance(DateFormat.LONG)); - if (this.displayFormat != null) { - try { - SimpleDateFormat displayFormat = new SimpleDateFormat( - (String) getParameters().get("displayFormat")); - formats.add(displayFormat); - } catch (Exception e) { - // don't use it then (this attribute is used by Dojo, not java code) - LOG.error(e); - } - } - - for (DateFormat format : formats) { - try { - date = format.parse(dateStr); - if (date != null) - return RFC3339_FORMAT.format(date); - } catch (Exception e) { - //keep going - } - } - - // last resource, assume already in correct/default format - if (LOG.isDebugEnabled()) - LOG.debug("Unable to parse date " + dateStr); - return dateStr; - } - } - -} +/* + * $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.dojo.components; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Random; + +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.components.UIBean; +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; + +/** + * + *

+ * Renders a date/time picker in a dropdown container. + *

+ *

+ * A stand-alone DateTimePicker widget that makes it easy to select a date/time, or increment by week, month, + * and/or year. + *

+ * + *

+ * 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.

+ *

+ * + * Syntax supported by 'displayFormat' is (http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns):- + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
FormatDescription
dDay of the month
DDay of year
MMonth - Use one or two for the numerical month, three for the abbreviation, or four for the full name, or 5 for the narrow name.
yYear
hHour [1-12].
HHour [0-23].
mMinute. Use one or two for zero padding.
sSecond. Use one or two for zero padding.
+ * + *

+ * The value sent to the server is a locale-independent value, in a hidden field as defined + * by the name attribute. The value will be formatted conforming to RFC3 339 + * (yyyy-MM-dd'T'HH:mm:ss) + *

+ *

+ * The following formats(in order) will be used to parse the values of the attributes 'value', + * 'startDate' and 'endDate': + *

+ *
    + *
  • SimpleDateFormat built using RFC 3339 (yyyy-MM-dd'T'HH:mm:ss) + *
  • SimpleDateFormat.getTimeInstance(DateFormat.SHORT) + *
  • SimpleDateFormat.getDateInstance(DateFormat.SHORT) + *
  • SimpleDateFormat.getDateInstance(DateFormat.MEDIUM) + *
  • SimpleDateFormat.getDateInstance(DateFormat.FULL) + *
  • SimpleDateFormat.getDateInstance(DateFormat.LONG) + *
  • SimpleDateFormat built using the value of the 'displayFormat' attribute(if any) + *
+ * + * + * Examples + * + *
+ * 
+ *
+ * Example 1:
+ *     <sx:datetimepicker name="order.date" label="Order Date" />
+ * Example 2:
+ *     <sx:datetimepicker name="delivery.date" label="Delivery Date" displayFormat="yyyy-MM-dd"  />
+ * Example 3:   
+ *      <sx:datetimepicker name="delivery.date" label="Delivery Date" value="%{date}"  />
+ * Example 4:    
+ *      <sx:datetimepicker name="delivery.date" label="Delivery Date" value="%{'2007-01-01'}"  />
+ * Example 5:           
+ *      <sx:datetimepicker name="order.date" label="Order Date" value="%{'today'}"/>
+ * 
+ * 
+ * + * + *

Getting and getting the datetimepicker value, from JavaScript

+ *
+ * <sx:datetimepicker id="picker" label="Order Date" />
+ * <script type="text/javascript">
+ *   function setValue() {
+ *      var picker = dojo.widget.byId("picker");
+ *      
+ *      //string value
+ *      picker.setValue('2007-01-01');
+ *      
+ *      //Date value
+ *      picker.setValue(new Date());
+ *   }
+ *   
+ *   function showValue() {
+ *      var picker = dojo.widget.byId("picker");
+ *      
+ *      //string value
+ *      var stringValue = picker.getValue();
+ *      alert(stringValue);
+ *      
+ *      //date value
+ *      var dateValue = picker.getDate();
+ *      alert(dateValue);
+ *   }
+ * </script>
+ * 
+ * + * + * + *

Publish topic when value changes

+ *
+ * <sx:datetimepicker id="picker" label="Order Date" valueNotifyTopics="/value"/>
+ * 
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/value", function(textEntered, date, widget){
+ *     alert('value changed');
+ *     //textEntered: String enetered in the textbox
+ *     //date: JavaScript Date object with the value selected
+ *     //widet: widget that published the topic 
+ * });
+ * </script>  
+ * 
+ * + */ +@StrutsTag(name="datetimepicker", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.DateTimePickerTag", description="Render datetimepicker") +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; + protected String valueNotifyTopics; + + public DateTimePicker(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + super(stack, request, response); + } + + protected String getDefaultTemplate() { + return TEMPLATE; + } + + public void evaluateParams() { + super.evaluateParams(); + + if(displayFormat != null) + addParameter("displayFormat", findString(displayFormat)); + if(displayWeeks != null) + addParameter("displayWeeks", findString(displayWeeks)); + if(adjustWeeks != null) + addParameter("adjustWeeks", findValue(adjustWeeks, Boolean.class)); + if(startDate != null) + addParameter("startDate", format(findValue(startDate))); + if(endDate != null) + addParameter("endDate", format(findValue(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", format(findValue(value))); + + if(iconPath != null) + addParameter("iconPath", findString(iconPath)); + if(formatLength != null) + addParameter("formatLength", findString(formatLength)); + 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)); + if(valueNotifyTopics != null) + addParameter("valueNotifyTopics", findString(valueNotifyTopics)); + + // format the value to RFC 3399 + if(parameters.containsKey("value")) { + parameters.put("nameValue", parameters.get("value")); + } else { + if(name != null) { + addParameter("nameValue", format(findValue(name))); + } + } + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + @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; + } + + @StrutsTagAttribute(description="Preset the value of input element") + public void setValue(String arg0) { + super.setValue(arg0); + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published when a value is selected") + public void setValueNotifyTopics(String valueNotifyTopics) { + this.valueNotifyTopics = valueNotifyTopics; + } + + private String format(Object obj) { + if(obj == null) + return null; + + if(obj instanceof Date) { + return RFC3339_FORMAT.format((Date) obj); + } else if(obj instanceof Calendar) { + return RFC3339_FORMAT.format(((Calendar) obj).getTime()); + } + else { + // try to parse a date + String dateStr = obj.toString(); + if(dateStr.equalsIgnoreCase("today")) + return RFC3339_FORMAT.format(new Date()); + + + Date date = null; + //formats used to parse the date + List formats = new ArrayList(); + formats.add(RFC3339_FORMAT); + formats.add(SimpleDateFormat.getTimeInstance(DateFormat.SHORT)); + formats.add(SimpleDateFormat.getDateInstance(DateFormat.SHORT)); + formats.add(SimpleDateFormat.getDateInstance(DateFormat.MEDIUM)); + formats.add(SimpleDateFormat.getDateInstance(DateFormat.FULL)); + formats.add(SimpleDateFormat.getDateInstance(DateFormat.LONG)); + if (this.displayFormat != null) { + try { + SimpleDateFormat displayFormat = new SimpleDateFormat( + (String) getParameters().get("displayFormat")); + formats.add(displayFormat); + } catch (Exception e) { + // don't use it then (this attribute is used by Dojo, not java code) + LOG.error(e); + } + } + + for (DateFormat format : formats) { + try { + date = format.parse(dateStr); + if (date != null) + return RFC3339_FORMAT.format(date); + } catch (Exception e) { + //keep going + } + } + + // last resource, assume already in correct/default format + if (LOG.isDebugEnabled()) + LOG.debug("Unable to parse date " + dateStr); + return dateStr; + } + } + +} diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Head.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Head.java index 14f7bf6b8..ca64d4d90 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Head.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Head.java @@ -76,13 +76,17 @@ import com.opensymphony.xwork2.util.ValueStack; * *

The "locale" attribute configures Dojo's locale:

* - * "The locale Dojo uses on a page may be overridden by setting djConfig.locale. This may be + *

"The locale Dojo uses on a page may be overridden by setting djConfig.locale. This may be * done to accomodate applications with a known user profile or server pages which do manual * assembly and assume a certain locale. You may also set djConfig.extraLocale to load * localizations in addition to your own, in case you want to specify a particular * translation or have multiple languages appear on your page."

* - *

Dojo 0.4.2 is distributed with the Dojo plugin, to use a different Dojo version, the + *

To improve loading time, the property "parseContent" is set to false by default. This property will + * instruct Dojo to only build widgets using specific element ids. If the property is set to true + * Dojo will scan the whole document looking for widgets.

+ * + *

Dojo 0.4.3 is distributed with the Dojo plugin, to use a different Dojo version, the * "baseRelativePath" attribute can be set to the URL of the Dojo root folder on your application. *

* @@ -113,13 +117,15 @@ import com.opensymphony.xwork2.util.ValueStack; @StrutsTagSkipInheritance public class Head extends org.apache.struts2.components.Head { public static final String TEMPLATE = "head"; - + public static final String PARSE_CONTENT = "struts.dojo.head.parseContent"; + private String debug; private String compressed; private String baseRelativePath; private String extraLocales; private String locale; private String cache; + private String parseContent; public Head(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { super(stack, request, response); @@ -146,6 +152,14 @@ public class Head extends org.apache.struts2.components.Head { addParameter("locale", findString(this.locale)); if (this.cache != null) addParameter("cache", findValue(this.cache, Boolean.class)); + if (this.parseContent != null) { + Boolean shouldParseContent = (Boolean) findValue(this.parseContent, Boolean.class); + addParameter("parseContent", shouldParseContent); + stack.getContext().put(PARSE_CONTENT, shouldParseContent); + } else { + addParameter("parseContent", false); + stack.getContext().put(PARSE_CONTENT, false); + } } @Override @@ -193,4 +207,9 @@ public class Head extends org.apache.struts2.components.Head { public void setCache(String cache) { this.cache = cache; } + + @StrutsTagAttribute(description="Parse the whole document for widgets", defaultValue="false", type="Boolean") + public void setParseContent(String parseContent) { + this.parseContent = parseContent; + } } diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Submit.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Submit.java index 98e075462..809f3b977 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Submit.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Submit.java @@ -1,466 +1,475 @@ -/* - * $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.dojo.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.components.Form; -import org.apache.struts2.components.FormButton; -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; - -/** - * - * Renders a submit button that can submit a form asynchronously. - * The submit can have three different types of rendering: - *
    - *
  • input: renders as html <input type="submit"...>
  • - *
  • image: renders as html <input type="image"...>
  • - *
  • button: renders as html <button type="submit"...>
  • - *
- * 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 - * - * - *

Examples

- *
- * 
- * <sx:submit value="%{'Submit'}" />
- * 
- * 
- *
- * 
- * Render an image submit:
- * <sx:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/>
- * 
- * 
- *
- * 
- * Render an button submit:
- * <sx:submit type="button" value="%{'Submit'}" label="Submit the form"/>
- * 
- * 
- * - * - *

Update target content with html returned from an action:

- *
- * <div id="div1">Div 1</div>
- * <s:url id="ajaxTest" value="/AjaxTest.action"/>
- * 
- * <sx:submit id="link1" href="%{ajaxTest}" target="div1" />
- * 
- * - * - * - *

Submit form(inside the form):

- *
- * <s:form id="form" action="AjaxTest">
- *      <input type="textbox" name="data">
- *      <sx:submit />          
- * </s:form>
- * 
- * - * - * - *

Submit form(outside the form)

- *
- * <s:form id="form" action="AjaxTest">
- *      <input type="textbox" name="data">   
- * </s:form>
- * 
- * <sx:submit formId="form" />
- * 
- * - * - * - *

Using beforeNotifyTopics:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/before", function(event, widget){
- *     alert('inside a topic event. before request');
- *     //event: set event.cancel = true, to cancel request
- *     //widget: widget that published the topic
- * });
- * </script>         
- * 
- * <sx:submit beforeNotifyTopics="/before" />
- * 
- * - * - * - *

Using afterNotifyTopics and highlight target:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/after", function(data, request, widget){
- *     alert('inside a topic event. after request');
- *     //data : text returned from request(the html)
- *     //request: XMLHttpRequest object
- *     //widget: widget that published the topic
- * });
- * </script>        
- * 
- * <sx:submit afterNotifyTopics="/after" highlightColor="red" href="%{#ajaxTest}" />
- * 
- * - * - * - *

Using errorNotifyTopics and indicator:

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/error", function(error, request, widget){
- *     alert('inside a topic event. on error');
- *     //error : error object (error.message has the error message)
- *     //request: XMLHttpRequest object
- *     //widget: widget that published the topic
- * });
- * </script>         
- * 
- * <img id="ind1" src="${pageContext.request.contextPath}/images/indicator.gif" style="display:none"/>
- * <sx:submit errorNotifyTopics="/error" indicator="ind1" href="%{#ajaxTest}" />
- * 
- * - */ -@StrutsTag(name="submit", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.SubmitTag", description="Render a submit button") -public class Submit extends FormButton implements RemoteBean { - - 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; - protected String targets; - protected String beforeNotifyTopics; - protected String afterNotifyTopics; - protected String errorNotifyTopics; - protected String highlightColor; - protected String highlightDuration; - protected String validate; - protected String ajaxAfterValidation; - protected String separateScripts; - protected String transport; - protected String parseContent; - - 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 (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)); - if (showLoadingText != null) - addParameter("showLoadingText", findString(showLoadingText)); - if (beforeNotifyTopics != null) - addParameter("beforeNotifyTopics", findString(beforeNotifyTopics)); - if (afterNotifyTopics != null) - addParameter("afterNotifyTopics", findString(afterNotifyTopics)); - if (errorNotifyTopics != null) - addParameter("errorNotifyTopics", findString(errorNotifyTopics)); - if (highlightColor != null) - addParameter("highlightColor", findString(highlightColor)); - if (highlightDuration != null) - addParameter("highlightDuration", findString(highlightDuration)); - if (separateScripts != null) - addParameter("separateScripts", findValue(separateScripts, Boolean.class)); - if (transport != null) - addParameter("transport", findString(transport)); - if (parseContent != null) - addParameter("parseContent", findValue(parseContent, Boolean.class)); - - Boolean validateValue = false; - if (validate != null) { - validateValue = (Boolean) findValue(validate, Boolean.class); - addParameter("validate", validateValue); - } - - Form form = (Form) findAncestor(Form.class); - if (form != null) - addParameter("parentTheme", form.getTheme()); - - if (ajaxAfterValidation != null) - addParameter("ajaxAfterValidation", findValue(ajaxAfterValidation, Boolean.class)); - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - /** - * Indicate whether the concrete button supports the type "image". - * - * @return true 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 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(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 image type submit button. Will have no effect for types input and button.") - 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="Comma delimmited list of topics that will published before and after the request, and on errors") - 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="false") - public void setShowLoadingText(String showLoadingText) { - this.showLoadingText = showLoadingText; - } - - @StrutsTagAttribute(description="The css class to use for element") - public void setCssClass(String cssClass) { - super.setCssClass(cssClass); - } - - @StrutsTagAttribute(description="The css style to use for element") - public void setCssStyle(String cssStyle) { - super.setCssStyle(cssStyle); - } - - @StrutsTagAttribute(description="The id to use for the element") - public void setId(String id) { - super.setId(id); - } - - @StrutsTagAttribute(description="The name to set for element") - public void setName(String name) { - super.setName(name); - } - - @StrutsTagAttribute(description="The type of submit to use. Valid values are input, " + - "button and image.", defaultValue="input") - public void setType(String type) { - super.setType(type); - } - - @StrutsTagAttribute(description="Preset the value of input element.") - public void setValue(String value) { - super.setValue(value); - } - - @StrutsTagAttribute(description="Label expression used for rendering a element specific label") - public void setLabel(String label) { - super.setLabel(label); - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)") - public void setAfterNotifyTopics(String afterNotifyTopics) { - this.afterNotifyTopics = afterNotifyTopics; - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request") - public void setBeforeNotifyTopics(String beforeNotifyTopics) { - this.beforeNotifyTopics = beforeNotifyTopics; - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)") - public void setErrorNotifyTopics(String errorNotifyTopics) { - this.errorNotifyTopics = errorNotifyTopics; - } - - @StrutsTagAttribute(description = "Color used to perform a highlight effect on the elements specified in the 'targets' attribute", - defaultValue = "none") - public void setHighlightColor(String highlightColor) { - this.highlightColor = highlightColor; - } - - @StrutsTagAttribute(description = "Duration of highlight effect in milliseconds. Only valid if 'highlightColor' attribute is set", - defaultValue = "1000") - public void setHighlightDuration(String highlightDuration) { - this.highlightDuration = highlightDuration; - } - - @StrutsTagAttribute(description = "Perform Ajax calidation. 'ajaxValidation' interceptor must be applied to action", type="Boolean", - defaultValue = "false") - public void setValidate(String validate) { - this.validate = validate; - } - - @StrutsTagAttribute(description = "Make an asynchronous request if validation succeeds. Only valid if 'validate' is 'true'", type="Boolean", - defaultValue = "false") - public void setAjaxAfterValidation(String ajaxAfterValidation) { - this.ajaxAfterValidation = ajaxAfterValidation; - } - - @StrutsTagSkipInheritance - public void setAction(String action) { - super.setAction(action); - } - - @StrutsTagAttribute(description="Run scripts in a separate scope, unique for each tag", defaultValue="true") - public void setSeparateScripts(String separateScripts) { - this.separateScripts = separateScripts; - } - - @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport") - public void setTransport(String transport) { - this.transport = transport; - } - - @StrutsTagAttribute(description="Parse returned HTML for Dojo widgets", defaultValue="true", type="Boolean") - public void setParseContent(String parseContent) { - this.parseContent = parseContent; - } -} +/* + * $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.dojo.components; + +import java.io.Writer; +import java.util.Random; + +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.components.Form; +import org.apache.struts2.components.FormButton; +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; + +/** + * + * Renders a submit button that can submit a form asynchronously. + * The submit can have three different types of rendering: + *
    + *
  • input: renders as html <input type="submit"...>
  • + *
  • image: renders as html <input type="image"...>
  • + *
  • button: renders as html <button type="submit"...>
  • + *
+ * 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 + * + * + *

Examples

+ *
+ * 
+ * <sx:submit value="%{'Submit'}" />
+ * 
+ * 
+ *
+ * 
+ * Render an image submit:
+ * <sx:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/>
+ * 
+ * 
+ *
+ * 
+ * Render an button submit:
+ * <sx:submit type="button" value="%{'Submit'}" label="Submit the form"/>
+ * 
+ * 
+ * + * + *

Update target content with html returned from an action:

+ *
+ * <div id="div1">Div 1</div>
+ * <s:url id="ajaxTest" value="/AjaxTest.action"/>
+ * 
+ * <sx:submit id="link1" href="%{ajaxTest}" target="div1" />
+ * 
+ * + * + * + *

Submit form(inside the form):

+ *
+ * <s:form id="form" action="AjaxTest">
+ *      <input type="textbox" name="data">
+ *      <sx:submit />          
+ * </s:form>
+ * 
+ * + * + * + *

Submit form(outside the form)

+ *
+ * <s:form id="form" action="AjaxTest">
+ *      <input type="textbox" name="data">   
+ * </s:form>
+ * 
+ * <sx:submit formId="form" />
+ * 
+ * + * + * + *

Using beforeNotifyTopics:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/before", function(event, widget){
+ *     alert('inside a topic event. before request');
+ *     //event: set event.cancel = true, to cancel request
+ *     //widget: widget that published the topic
+ * });
+ * </script>         
+ * 
+ * <sx:submit beforeNotifyTopics="/before" />
+ * 
+ * + * + * + *

Using afterNotifyTopics and highlight target:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/after", function(data, request, widget){
+ *     alert('inside a topic event. after request');
+ *     //data : text returned from request(the html)
+ *     //request: XMLHttpRequest object
+ *     //widget: widget that published the topic
+ * });
+ * </script>        
+ * 
+ * <sx:submit afterNotifyTopics="/after" highlightColor="red" href="%{#ajaxTest}" />
+ * 
+ * + * + * + *

Using errorNotifyTopics and indicator:

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/error", function(error, request, widget){
+ *     alert('inside a topic event. on error');
+ *     //error : error object (error.message has the error message)
+ *     //request: XMLHttpRequest object
+ *     //widget: widget that published the topic
+ * });
+ * </script>         
+ * 
+ * <img id="ind1" src="${pageContext.request.contextPath}/images/indicator.gif" style="display:none"/>
+ * <sx:submit errorNotifyTopics="/error" indicator="ind1" href="%{#ajaxTest}" />
+ * 
+ * + */ +@StrutsTag(name="submit", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.SubmitTag", description="Render a submit button") +public class Submit extends FormButton implements RemoteBean { + + 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; + protected String targets; + protected String beforeNotifyTopics; + protected String afterNotifyTopics; + protected String errorNotifyTopics; + protected String highlightColor; + protected String highlightDuration; + protected String validate; + protected String ajaxAfterValidation; + protected String separateScripts; + protected String transport; + protected String parseContent; + + 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 (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)); + if (showLoadingText != null) + addParameter("showLoadingText", findString(showLoadingText)); + if (beforeNotifyTopics != null) + addParameter("beforeNotifyTopics", findString(beforeNotifyTopics)); + if (afterNotifyTopics != null) + addParameter("afterNotifyTopics", findString(afterNotifyTopics)); + if (errorNotifyTopics != null) + addParameter("errorNotifyTopics", findString(errorNotifyTopics)); + if (highlightColor != null) + addParameter("highlightColor", findString(highlightColor)); + if (highlightDuration != null) + addParameter("highlightDuration", findString(highlightDuration)); + if (separateScripts != null) + addParameter("separateScripts", findValue(separateScripts, Boolean.class)); + if (transport != null) + addParameter("transport", findString(transport)); + if (parseContent != null) + addParameter("parseContent", findValue(parseContent, Boolean.class)); + + Boolean validateValue = false; + if (validate != null) { + validateValue = (Boolean) findValue(validate, Boolean.class); + addParameter("validate", validateValue); + } + + Form form = (Form) findAncestor(Form.class); + if (form != null) + addParameter("parentTheme", form.getTheme()); + + if (ajaxAfterValidation != null) + addParameter("ajaxAfterValidation", findValue(ajaxAfterValidation, Boolean.class)); + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + /** + * Indicate whether the concrete button supports the type "image". + * + * @return true 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 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(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 image type submit button. Will have no effect for types input and button.") + 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="Comma delimmited list of topics that will published before and after the request, and on errors") + 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="false") + public void setShowLoadingText(String showLoadingText) { + this.showLoadingText = showLoadingText; + } + + @StrutsTagAttribute(description="The css class to use for element") + public void setCssClass(String cssClass) { + super.setCssClass(cssClass); + } + + @StrutsTagAttribute(description="The css style to use for element") + public void setCssStyle(String cssStyle) { + super.setCssStyle(cssStyle); + } + + @StrutsTagAttribute(description="The id to use for the element") + public void setId(String id) { + super.setId(id); + } + + @StrutsTagAttribute(description="The name to set for element") + public void setName(String name) { + super.setName(name); + } + + @StrutsTagAttribute(description="The type of submit to use. Valid values are input, " + + "button and image.", defaultValue="input") + public void setType(String type) { + super.setType(type); + } + + @StrutsTagAttribute(description="Preset the value of input element.") + public void setValue(String value) { + super.setValue(value); + } + + @StrutsTagAttribute(description="Label expression used for rendering a element specific label") + public void setLabel(String label) { + super.setLabel(label); + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)") + public void setAfterNotifyTopics(String afterNotifyTopics) { + this.afterNotifyTopics = afterNotifyTopics; + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request") + public void setBeforeNotifyTopics(String beforeNotifyTopics) { + this.beforeNotifyTopics = beforeNotifyTopics; + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)") + public void setErrorNotifyTopics(String errorNotifyTopics) { + this.errorNotifyTopics = errorNotifyTopics; + } + + @StrutsTagAttribute(description = "Color used to perform a highlight effect on the elements specified in the 'targets' attribute", + defaultValue = "none") + public void setHighlightColor(String highlightColor) { + this.highlightColor = highlightColor; + } + + @StrutsTagAttribute(description = "Duration of highlight effect in milliseconds. Only valid if 'highlightColor' attribute is set", + defaultValue = "1000") + public void setHighlightDuration(String highlightDuration) { + this.highlightDuration = highlightDuration; + } + + @StrutsTagAttribute(description = "Perform Ajax calidation. 'ajaxValidation' interceptor must be applied to action", type="Boolean", + defaultValue = "false") + public void setValidate(String validate) { + this.validate = validate; + } + + @StrutsTagAttribute(description = "Make an asynchronous request if validation succeeds. Only valid if 'validate' is 'true'", type="Boolean", + defaultValue = "false") + public void setAjaxAfterValidation(String ajaxAfterValidation) { + this.ajaxAfterValidation = ajaxAfterValidation; + } + + @StrutsTagSkipInheritance + public void setAction(String action) { + super.setAction(action); + } + + @StrutsTagAttribute(description="Run scripts in a separate scope, unique for each tag", defaultValue="true") + public void setSeparateScripts(String separateScripts) { + this.separateScripts = separateScripts; + } + + @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport") + public void setTransport(String transport) { + this.transport = transport; + } + + @StrutsTagAttribute(description="Parse returned HTML for Dojo widgets", defaultValue="true", type="Boolean") + public void setParseContent(String parseContent) { + this.parseContent = parseContent; + } +} diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TabbedPanel.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TabbedPanel.java index cd0d7c84e..9023b4063 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TabbedPanel.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TabbedPanel.java @@ -1,214 +1,223 @@ -/* - * $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.dojo.components; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.components.ClosingUIBean; -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; - -/** - * - * 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).

- * If the useSelectedTabCookie attribute is set to true, the id of the selected tab is saved in a cookie on activation. - * When coming back to this view, the cookie is read and the tab will be activated again, unless an actual value for the - * selectedTab attribute is specified.

- * If you want to use the cookie feature, please be sure that you provide a unique id for your tabbedpanel component, - * since this will also be the identifying name component of the stored cookie.

- * - * - *

Examples - *

- * - * The following is an example of a tabbedpanel and panel tag utilizing local and remote content.

- * - * - * - *

- * <s:tabbedpanel id="test" >
- *    <s:div id="one" label="one" theme="ajax" labelposition="top" >
- *        This is the first pane<br/>
- *        <s:form>
- *            <s:textfield name="tt" label="Test Text"/>  <br/>
- *            <s:textfield name="tt2" label="Test Text2"/>
- *        </s:form>
- *    </s:div>
- *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
- *        This is the remote tab
- *    </s:div>
- * </s:tabbedpanel>
- * 
- * - * - * - *

Use notify topics to prevent a tab from being selected

- *
- * <script type="text/javascript">
- * dojo.event.topic.subscribe("/beforeSelect", function(event, tab, tabContainer){
- *     event.cancel = true;
- * });
- * </script>
- * 
- * <s:tabbedpanel id="test" beforeSelectTabNotifyTopics="/beforeSelect">
- *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
- *        One Tab
- *    </s:div>
- *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
- *        Another tab
- *    </s:div>
- * </s:tabbedpanel>
- * 
- * - */ -@StrutsTag(name="tabbedpanel", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TabbedPanelTag", description="Render a tabbedPanel widget.") -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; - protected String beforeSelectTabNotifyTopics; - protected String afterSelectTabNotifyTopics; - protected String disabledTabCssClass; - protected String useSelectedTabCookie; - - 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)); - if (beforeSelectTabNotifyTopics!= null) - addParameter("beforeSelectTabNotifyTopics", findString(beforeSelectTabNotifyTopics)); - if (afterSelectTabNotifyTopics!= null) - addParameter("afterSelectTabNotifyTopics", findString(afterSelectTabNotifyTopics)); - if (disabledTabCssClass!= null) - addParameter("disabledTabCssClass", findString(disabledTabCssClass)); - if(useSelectedTabCookie != null) { - addParameter("useSelectedTabCookie", findString(useSelectedTabCookie)); - } - - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - 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="Deprecated. Use 'closable' on each div(tab)") - 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; - } - - - @StrutsTagAttribute(description="Comma separated list of topics to be published when a tab is clicked on (before it is selected)" + - "The tab container widget will be passed as the first argument to the topic. The second parameter is the tab widget." + - "The event can be cancelled setting to 'true' the 'cancel' property " + - "of the third parameter passed to the topics.") - public void setBeforeSelectTabNotifyTopics(String selectedTabNotifyTopics) { - this.beforeSelectTabNotifyTopics = selectedTabNotifyTopics; - } - - @StrutsTagAttribute(description="Comma separated list of topics to be published when a tab is clicked on (after it is selected)." + - "The tab container widget will be passed as the first argument to the topic. The second parameter is the tab widget.") - public void setAfterSelectTabNotifyTopics(String afterSelectTabNotifyTopics) { - this.afterSelectTabNotifyTopics = afterSelectTabNotifyTopics; - } - - @StrutsTagAttribute(description="Css class to be applied to the tab button of disabled tabs", defaultValue="strutsDisabledTab") - public void setDisabledTabCssClass(String disabledTabCssClass) { - this.disabledTabCssClass = disabledTabCssClass; - } - - @StrutsTagAttribute(required = false, defaultValue = "false", description = "If set to true, the id of the last selected " + - "tab will be stored in cookie. If the view is rendered, it will be tried to read this cookie and activate " + - "the corresponding tab on success, unless overridden by the selectedTab attribute. The cookie name is \"Struts2TabbedPanel_selectedTab_\"+id.") - public void setUseSelectedTabCookie( String useSelectedTabCookie ) { - this.useSelectedTabCookie = useSelectedTabCookie; - } -} +/* + * $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.dojo.components; + +import java.util.Random; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts2.components.ClosingUIBean; +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; + +/** + * + * 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).

+ * If the useSelectedTabCookie attribute is set to true, the id of the selected tab is saved in a cookie on activation. + * When coming back to this view, the cookie is read and the tab will be activated again, unless an actual value for the + * selectedTab attribute is specified.

+ * If you want to use the cookie feature, please be sure that you provide a unique id for your tabbedpanel component, + * since this will also be the identifying name component of the stored cookie.

+ * + * + *

Examples + *

+ * + * The following is an example of a tabbedpanel and panel tag utilizing local and remote content.

+ * + * + * + *

+ * <s:tabbedpanel id="test" >
+ *    <s:div id="one" label="one" theme="ajax" labelposition="top" >
+ *        This is the first pane<br/>
+ *        <s:form>
+ *            <s:textfield name="tt" label="Test Text"/>  <br/>
+ *            <s:textfield name="tt2" label="Test Text2"/>
+ *        </s:form>
+ *    </s:div>
+ *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
+ *        This is the remote tab
+ *    </s:div>
+ * </s:tabbedpanel>
+ * 
+ * + * + * + *

Use notify topics to prevent a tab from being selected

+ *
+ * <script type="text/javascript">
+ * dojo.event.topic.subscribe("/beforeSelect", function(event, tab, tabContainer){
+ *     event.cancel = true;
+ * });
+ * </script>
+ * 
+ * <s:tabbedpanel id="test" beforeSelectTabNotifyTopics="/beforeSelect">
+ *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
+ *        One Tab
+ *    </s:div>
+ *    <s:div id="three" label="remote" theme="ajax" href="/AjaxTest.action" >
+ *        Another tab
+ *    </s:div>
+ * </s:tabbedpanel>
+ * 
+ * + */ +@StrutsTag(name="tabbedpanel", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TabbedPanelTag", description="Render a tabbedPanel widget.") +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; + protected String beforeSelectTabNotifyTopics; + protected String afterSelectTabNotifyTopics; + protected String disabledTabCssClass; + protected String useSelectedTabCookie; + + 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)); + if (beforeSelectTabNotifyTopics!= null) + addParameter("beforeSelectTabNotifyTopics", findString(beforeSelectTabNotifyTopics)); + if (afterSelectTabNotifyTopics!= null) + addParameter("afterSelectTabNotifyTopics", findString(afterSelectTabNotifyTopics)); + if (disabledTabCssClass!= null) + addParameter("disabledTabCssClass", findString(disabledTabCssClass)); + if(useSelectedTabCookie != null) { + addParameter("useSelectedTabCookie", findString(useSelectedTabCookie)); + } + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + 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="Deprecated. Use 'closable' on each div(tab)") + 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; + } + + + @StrutsTagAttribute(description="Comma separated list of topics to be published when a tab is clicked on (before it is selected)" + + "The tab container widget will be passed as the first argument to the topic. The second parameter is the tab widget." + + "The event can be cancelled setting to 'true' the 'cancel' property " + + "of the third parameter passed to the topics.") + public void setBeforeSelectTabNotifyTopics(String selectedTabNotifyTopics) { + this.beforeSelectTabNotifyTopics = selectedTabNotifyTopics; + } + + @StrutsTagAttribute(description="Comma separated list of topics to be published when a tab is clicked on (after it is selected)." + + "The tab container widget will be passed as the first argument to the topic. The second parameter is the tab widget.") + public void setAfterSelectTabNotifyTopics(String afterSelectTabNotifyTopics) { + this.afterSelectTabNotifyTopics = afterSelectTabNotifyTopics; + } + + @StrutsTagAttribute(description="Css class to be applied to the tab button of disabled tabs", defaultValue="strutsDisabledTab") + public void setDisabledTabCssClass(String disabledTabCssClass) { + this.disabledTabCssClass = disabledTabCssClass; + } + + @StrutsTagAttribute(required = false, defaultValue = "false", description = "If set to true, the id of the last selected " + + "tab will be stored in cookie. If the view is rendered, it will be tried to read this cookie and activate " + + "the corresponding tab on success, unless overridden by the selectedTab attribute. The cookie name is \"Struts2TabbedPanel_selectedTab_\"+id.") + public void setUseSelectedTabCookie( String useSelectedTabCookie ) { + this.useSelectedTabCookie = useSelectedTabCookie; + } +} diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Tree.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Tree.java index 1b8b07198..5e03a4c25 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Tree.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/Tree.java @@ -1,535 +1,556 @@ -/* - * $Id: Tree.java 497654 2007-01-19 00:21:57Z rgielen $ - * - * 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.dojo.components; - -import java.io.Writer; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.components.ClosingUIBean; -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; - -/** - * - * - * Renders a tree widget with AJAX support.

- * - * The "id "attribute is normally specified(recommended), such that it could be looked up using - * javascript if necessary. The "id" attribute is required if the "selectedNotifyTopic" or the - * "href" attributes are going to be used.

- * - * - * - * - *

- * 

Tree loaded statically

- * <s:tree id="..." label="..."> - * <s:treenode id="..." label="..." /> - * <s:treenode id="..." label="..."> - * <s:treenode id="..." label="..." /> - * <s:treenode id="..." label="..." /> - * &;lt;/s:treenode> - * <s:treenode id="..." label="..." /> - * </s:tree> - *
- * - * - * - *

Tree loaded dynamically

- *
- * <s:tree
- *          id="..."
- *          rootNode="..."
- *          nodeIdProperty="..."
- *          nodeTitleProperty="..."
- *          childCollectionProperty="..." />
- * 
- * - * - * - *

Tree loaded dynamically using AJAX

- *
- * <s:url id="nodesUrl" namespace="/nodecorate" action="getNodes" />
- * <div style="float:left; margin-right: 50px;">
- *     <sx:tree id="tree" href="%{#nodesUrl}" />
- * </div>
- * 
- * - *

On this example the url specified on the "href" attibute will be called to load - * the elements on the root. The response is expected to be a JSON array of objects like: - *

- *
- * [
- *      {
- *           label: "Node 1",
- *           hasChildren: false,
- *           id: "Node1"
- *      },
- *      {
- *           label: "Node 2",
- *           hasChildren: true,
- *           id: "Node2"
- *      },
- * ]
- * 
- * - *

"label" is the text that will be displayed for the node. "hasChildren" marks the node has - * having children or not (if true, a plus icon will be assigned to the node so it can be - * expanded). The "id" attribute will be used to load the children of the node, when the node - * is expanded. When a node is expanded a request will be made to the url in the "href" attribute - * and the node's "id" will be passed in the parameter "nodeId".

- * - *

The children collection for a node will be loaded only once, to reload the children of a - * node, use the "reload()" function of the treenode widget. To reload the children nodes of "Node1" - * from the example above use the following javascript: - * - *

- * dojo.widget.byId("Node1").reload();
- * 
- * - */ -@StrutsTag(name="tree", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TreeTag", description="Render a tree widget.") -public class Tree extends ClosingUIBean { - - private static final String TEMPLATE = "tree-close"; - private static final String OPEN_TEMPLATE = "tree"; - - protected String toggle; - protected String selectedNotifyTopics; - protected String expandedNotifyTopics; - protected String collapsedNotifyTopics; - protected String rootNodeAttr; - protected String childCollectionProperty; - protected String nodeTitleProperty; - protected String nodeIdProperty; - protected String showRootGrid; - - protected String showGrid; - protected String blankIconSrc; - protected String gridIconSrcL; - protected String gridIconSrcV; - protected String gridIconSrcP; - protected String gridIconSrcC; - protected String gridIconSrcX; - protected String gridIconSrcY; - protected String expandIconSrcPlus; - protected String expandIconSrcMinus; - protected String iconWidth; - protected String iconHeight; - protected String toggleDuration; - protected String templateCssPath; - protected String href; - protected String errorNotifyTopics; - - public Tree(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { - super(stack, request, response); - } - - public boolean start(Writer writer) { - boolean result = super.start(writer); - - if (this.label == null && (href == null)) { - if ((rootNodeAttr == null) - || (childCollectionProperty == null) - || (nodeTitleProperty == null) - || (nodeIdProperty == null)) { - fieldError("label","The TreeTag requires either a value for 'label' or 'href' or ALL of 'rootNode', " + - "'childCollectionProperty', 'nodeTitleProperty', and 'nodeIdProperty'", null); - } - } - return result; - } - - protected void evaluateExtraParams() { - super.evaluateExtraParams(); - - if (toggle != null) { - addParameter("toggle", findString(toggle)); - } else { - addParameter("toggle", "fade"); - } - - if (selectedNotifyTopics != null) { - addParameter("selectedNotifyTopics", findString(selectedNotifyTopics)); - } - - if (expandedNotifyTopics != null) { - addParameter("expandedNotifyTopics", findString(expandedNotifyTopics)); - } - - if (collapsedNotifyTopics != null) { - addParameter("collapsedNotifyTopics", findString(collapsedNotifyTopics)); - } - - if (rootNodeAttr != null) { - addParameter("rootNode", findValue(rootNodeAttr)); - } - - if (childCollectionProperty != null) { - addParameter("childCollectionProperty", findString(childCollectionProperty)); - } - - if (nodeTitleProperty != null) { - addParameter("nodeTitleProperty", findString(nodeTitleProperty)); - } - - if (nodeIdProperty != null) { - addParameter("nodeIdProperty", findString(nodeIdProperty)); - } - - if (showRootGrid != null) { - addParameter("showRootGrid", findValue(showRootGrid, Boolean.class)); - } - - - if (showGrid != null) { - addParameter("showGrid", findValue(showGrid, Boolean.class)); - } - - if (blankIconSrc != null) { - addParameter("blankIconSrc", findString(blankIconSrc)); - } - - if (gridIconSrcL != null) { - addParameter("gridIconSrcL", findString(gridIconSrcL)); - } - - if (gridIconSrcV != null) { - addParameter("gridIconSrcV", findString(gridIconSrcV)); - } - - if (gridIconSrcP != null) { - addParameter("gridIconSrcP", findString(gridIconSrcP)); - } - - if (gridIconSrcC != null) { - addParameter("gridIconSrcC", findString(gridIconSrcC)); - } - - if (gridIconSrcX != null) { - addParameter("gridIconSrcX", findString(gridIconSrcX)); - } - - if (gridIconSrcY != null) { - addParameter("gridIconSrcY", findString(gridIconSrcY)); - } - - if (expandIconSrcPlus != null) { - addParameter("expandIconSrcPlus", findString(expandIconSrcPlus)); - } - - if (expandIconSrcMinus != null) { - addParameter("expandIconSrcMinus", findString(expandIconSrcMinus)); - } - - if (iconWidth != null) { - addParameter("iconWidth", findValue(iconWidth, Integer.class)); - } - if (iconHeight != null) { - addParameter("iconHeight", findValue(iconHeight, Integer.class)); - } - if (toggleDuration != null) { - addParameter("toggleDuration", findValue(toggleDuration, Integer.class)); - } - if (templateCssPath != null) { - addParameter("templateCssPath", findString(templateCssPath)); - } - if (href != null) - addParameter("href", findString(href)); - if (errorNotifyTopics != null) - addParameter("errorNotifyTopics", findString(errorNotifyTopics)); - - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - public String getDefaultOpenTemplate() { - return OPEN_TEMPLATE; - } - - protected String getDefaultTemplate() { - return TEMPLATE; - } - - public String getToggle() { - return toggle; - } - - @StrutsTagAttribute(description="The toggle property (either 'explode' or 'fade')", defaultValue="fade") - public void setToggle(String toggle) { - this.toggle = toggle; - } - - @StrutsTagAttribute(description="Deprecated. Use 'selectedNotifyTopics' instead.") - public void setTreeSelectedTopic(String selectedNotifyTopic) { - this.selectedNotifyTopics = selectedNotifyTopic; - } - - @StrutsTagAttribute(description="Deprecated. Use 'expandedNotifyTopics' instead.") - public void setTreeExpandedTopics(String expandedNotifyTopic) { - this.expandedNotifyTopics = expandedNotifyTopic; - } - - @StrutsTagAttribute(description="Deprecated. Use 'collapsedNotifyTopics' instead.") - public void setTreeCollapsedTopics(String collapsedNotifyTopic) { - this.collapsedNotifyTopics = collapsedNotifyTopic; - } - - public String getRootNode() { - return rootNodeAttr; - } - - @StrutsTagAttribute(description="The rootNode property.") - public void setRootNode(String rootNode) { - this.rootNodeAttr = rootNode; - } - - public String getChildCollectionProperty() { - return childCollectionProperty; - } - - @StrutsTagAttribute(description="The childCollectionProperty property.") - public void setChildCollectionProperty(String childCollectionProperty) { - this.childCollectionProperty = childCollectionProperty; - } - - public String getNodeTitleProperty() { - return nodeTitleProperty; - } - - @StrutsTagAttribute(description="The nodeTitleProperty property.") - public void setNodeTitleProperty(String nodeTitleProperty) { - this.nodeTitleProperty = nodeTitleProperty; - } - - public String getNodeIdProperty() { - return nodeIdProperty; - } - - @StrutsTagAttribute(description="The nodeIdProperty property.") - public void setNodeIdProperty(String nodeIdProperty) { - this.nodeIdProperty = nodeIdProperty; - } - - @StrutsTagAttribute(description="The showRootGrid property (default true).") - public void setShowRootGrid(String showRootGrid) { - this.showRootGrid = showRootGrid; - } - - public String getShowRootGrid() { - return showRootGrid; - } - - public String getBlankIconSrc() { - return blankIconSrc; - } - - @StrutsTagAttribute(description="Blank icon image source.") - public void setBlankIconSrc(String blankIconSrc) { - this.blankIconSrc = blankIconSrc; - } - - public String getExpandIconSrcMinus() { - return expandIconSrcMinus; - } - - @StrutsTagAttribute(description="Expand icon (-) image source.") - public void setExpandIconSrcMinus(String expandIconSrcMinus) { - this.expandIconSrcMinus = expandIconSrcMinus; - } - - public String getExpandIconSrcPlus() { - return expandIconSrcPlus; - } - - @StrutsTagAttribute(description="Expand Icon (+) image source.") - public void setExpandIconSrcPlus(String expandIconSrcPlus) { - this.expandIconSrcPlus = expandIconSrcPlus; - } - - public String getGridIconSrcC() { - return gridIconSrcC; - } - - @StrutsTagAttribute(description="Image source for under child item child icons.") - public void setGridIconSrcC(String gridIconSrcC) { - this.gridIconSrcC = gridIconSrcC; - } - - public String getGridIconSrcL() { - return gridIconSrcL; - } - - - @StrutsTagAttribute(description=" Image source for last child grid.") - public void setGridIconSrcL(String gridIconSrcL) { - this.gridIconSrcL = gridIconSrcL; - } - - public String getGridIconSrcP() { - return gridIconSrcP; - } - - @StrutsTagAttribute(description="Image source for under parent item child icons.") - public void setGridIconSrcP(String gridIconSrcP) { - this.gridIconSrcP = gridIconSrcP; - } - - public String getGridIconSrcV() { - return gridIconSrcV; - } - - @StrutsTagAttribute(description="Image source for vertical line.") - public void setGridIconSrcV(String gridIconSrcV) { - this.gridIconSrcV = gridIconSrcV; - } - - public String getGridIconSrcX() { - return gridIconSrcX; - } - - @StrutsTagAttribute(description="Image source for grid for sole root item.") - public void setGridIconSrcX(String gridIconSrcX) { - this.gridIconSrcX = gridIconSrcX; - } - - public String getGridIconSrcY() { - return gridIconSrcY; - } - - @StrutsTagAttribute(description="Image source for grid for last root item.") - public void setGridIconSrcY(String gridIconSrcY) { - this.gridIconSrcY = gridIconSrcY; - } - - public String getIconHeight() { - return iconHeight; - } - - - @StrutsTagAttribute(description="Icon height", defaultValue="18px") - public void setIconHeight(String iconHeight) { - this.iconHeight = iconHeight; - } - - public String getIconWidth() { - return iconWidth; - } - - @StrutsTagAttribute(description="Icon width", defaultValue="19px") - public void setIconWidth(String iconWidth) { - this.iconWidth = iconWidth; - } - - - - public String getTemplateCssPath() { - return templateCssPath; - } - - @StrutsTagAttribute(description="Template css path", defaultValue="{contextPath}/struts/tree.css.") - public void setTemplateCssPath(String templateCssPath) { - this.templateCssPath = templateCssPath; - } - - public String getToggleDuration() { - return toggleDuration; - } - - @StrutsTagAttribute(description="Toggle duration in milliseconds", defaultValue="150") - public void setToggleDuration(String toggleDuration) { - this.toggleDuration = toggleDuration; - } - - public String getShowGrid() { - return showGrid; - } - - @StrutsTagAttribute(description="Show grid", type="Boolean", defaultValue="true") - public void setShowGrid(String showGrid) { - this.showGrid = showGrid; - } - - @StrutsTagAttribute(description="The css class to use for element") - public void setCssClass(String cssClass) { - super.setCssClass(cssClass); - } - - @StrutsTagAttribute(description="The css style to use for element") - public void setCssStyle(String cssStyle) { - super.setCssStyle(cssStyle); - } - - @StrutsTagAttribute(description="The id to use for the element") - public void setId(String id) { - super.setId(id); - } - - @StrutsTagAttribute(description="The name to set for element") - public void setName(String name) { - super.setName(name); - } - - @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + - " is collapsed. An object with a 'node' property will be passed as parameter to the topics.") - public void setCollapsedNotifyTopics(String collapsedNotifyTopics) { - this.collapsedNotifyTopics = collapsedNotifyTopics; - } - - @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + - " is expanded. An object with a 'node' property will be passed as parameter to the topics.") - public void setExpandedNotifyTopics(String expandedNotifyTopics) { - this.expandedNotifyTopics= expandedNotifyTopics; - } - - @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + - " is selected. An object with a 'node' property will be passed as parameter to the topics.") - public void setSelectedNotifyTopics(String selectedNotifyTopics) { - this.selectedNotifyTopics = selectedNotifyTopics; - } - - @StrutsTagAttribute(description="Url used to load the list of children nodes for an specific node, whose id will be " + - "passed as a parameter named 'nodeId' (empty for root)") - public void setHref(String href) { - this.href = href; - } - - @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)." + - "Only valid if 'href' is set") - public void setErrorNotifyTopics(String errorNotifyTopics) { - this.errorNotifyTopics = errorNotifyTopics; - } -} - +/* + * $Id: Tree.java 497654 2007-01-19 00:21:57Z rgielen $ + * + * 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.dojo.components; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts2.components.ClosingUIBean; +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; + +/** + * + * + * Renders a tree widget with AJAX support.

+ * + * The "id "attribute is normally specified(recommended), such that it could be looked up using + * javascript if necessary. The "id" attribute is required if the "selectedNotifyTopic" or the + * "href" attributes are going to be used.

+ * + * + * + * + *

+ * 

Tree loaded statically

+ * <s:tree id="..." label="..."> + * <s:treenode id="..." label="..." /> + * <s:treenode id="..." label="..."> + * <s:treenode id="..." label="..." /> + * <s:treenode id="..." label="..." /> + * &;lt;/s:treenode> + * <s:treenode id="..." label="..." /> + * </s:tree> + *
+ * + * + * + *

Tree loaded dynamically

+ *
+ * <s:tree
+ *          id="..."
+ *          rootNode="..."
+ *          nodeIdProperty="..."
+ *          nodeTitleProperty="..."
+ *          childCollectionProperty="..." />
+ * 
+ * + * + * + *

Tree loaded dynamically using AJAX

+ *
+ * <s:url id="nodesUrl" namespace="/nodecorate" action="getNodes" />
+ * <div style="float:left; margin-right: 50px;">
+ *     <sx:tree id="tree" href="%{#nodesUrl}" />
+ * </div>
+ * 
+ * + *

On this example the url specified on the "href" attibute will be called to load + * the elements on the root. The response is expected to be a JSON array of objects like: + *

+ *
+ * [
+ *      {
+ *           label: "Node 1",
+ *           hasChildren: false,
+ *           id: "Node1"
+ *      },
+ *      {
+ *           label: "Node 2",
+ *           hasChildren: true,
+ *           id: "Node2"
+ *      },
+ * ]
+ * 
+ * + *

"label" is the text that will be displayed for the node. "hasChildren" marks the node has + * having children or not (if true, a plus icon will be assigned to the node so it can be + * expanded). The "id" attribute will be used to load the children of the node, when the node + * is expanded. When a node is expanded a request will be made to the url in the "href" attribute + * and the node's "id" will be passed in the parameter "nodeId".

+ * + *

The children collection for a node will be loaded only once, to reload the children of a + * node, use the "reload()" function of the treenode widget. To reload the children nodes of "Node1" + * from the example above use the following javascript: + * + *

+ * dojo.widget.byId("Node1").reload();
+ * 
+ * + */ +@StrutsTag(name="tree", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TreeTag", description="Render a tree widget.") +public class Tree extends ClosingUIBean { + + private static final String TEMPLATE = "tree-close"; + private static final String OPEN_TEMPLATE = "tree"; + + protected String toggle; + protected String selectedNotifyTopics; + protected String expandedNotifyTopics; + protected String collapsedNotifyTopics; + protected String rootNodeAttr; + protected String childCollectionProperty; + protected String nodeTitleProperty; + protected String nodeIdProperty; + protected String showRootGrid; + + protected String showGrid; + protected String blankIconSrc; + protected String gridIconSrcL; + protected String gridIconSrcV; + protected String gridIconSrcP; + protected String gridIconSrcC; + protected String gridIconSrcX; + protected String gridIconSrcY; + protected String expandIconSrcPlus; + protected String expandIconSrcMinus; + protected String iconWidth; + protected String iconHeight; + protected String toggleDuration; + protected String templateCssPath; + protected String href; + protected String errorNotifyTopics; + + private List childrenIds; + + public Tree(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + super(stack, request, response); + } + + public boolean start(Writer writer) { + boolean result = super.start(writer); + + if (this.label == null && (href == null)) { + if ((rootNodeAttr == null) + || (childCollectionProperty == null) + || (nodeTitleProperty == null) + || (nodeIdProperty == null)) { + fieldError("label","The TreeTag requires either a value for 'label' or 'href' or ALL of 'rootNode', " + + "'childCollectionProperty', 'nodeTitleProperty', and 'nodeIdProperty'", null); + } + } + return result; + } + + protected void evaluateExtraParams() { + super.evaluateExtraParams(); + + if (toggle != null) { + addParameter("toggle", findString(toggle)); + } else { + addParameter("toggle", "fade"); + } + + if (selectedNotifyTopics != null) { + addParameter("selectedNotifyTopics", findString(selectedNotifyTopics)); + } + + if (expandedNotifyTopics != null) { + addParameter("expandedNotifyTopics", findString(expandedNotifyTopics)); + } + + if (collapsedNotifyTopics != null) { + addParameter("collapsedNotifyTopics", findString(collapsedNotifyTopics)); + } + + if (rootNodeAttr != null) { + addParameter("rootNode", findValue(rootNodeAttr)); + } + + if (childCollectionProperty != null) { + addParameter("childCollectionProperty", findString(childCollectionProperty)); + } + + if (nodeTitleProperty != null) { + addParameter("nodeTitleProperty", findString(nodeTitleProperty)); + } + + if (nodeIdProperty != null) { + addParameter("nodeIdProperty", findString(nodeIdProperty)); + } + + if (showRootGrid != null) { + addParameter("showRootGrid", findValue(showRootGrid, Boolean.class)); + } + + + if (showGrid != null) { + addParameter("showGrid", findValue(showGrid, Boolean.class)); + } + + if (blankIconSrc != null) { + addParameter("blankIconSrc", findString(blankIconSrc)); + } + + if (gridIconSrcL != null) { + addParameter("gridIconSrcL", findString(gridIconSrcL)); + } + + if (gridIconSrcV != null) { + addParameter("gridIconSrcV", findString(gridIconSrcV)); + } + + if (gridIconSrcP != null) { + addParameter("gridIconSrcP", findString(gridIconSrcP)); + } + + if (gridIconSrcC != null) { + addParameter("gridIconSrcC", findString(gridIconSrcC)); + } + + if (gridIconSrcX != null) { + addParameter("gridIconSrcX", findString(gridIconSrcX)); + } + + if (gridIconSrcY != null) { + addParameter("gridIconSrcY", findString(gridIconSrcY)); + } + + if (expandIconSrcPlus != null) { + addParameter("expandIconSrcPlus", findString(expandIconSrcPlus)); + } + + if (expandIconSrcMinus != null) { + addParameter("expandIconSrcMinus", findString(expandIconSrcMinus)); + } + + if (iconWidth != null) { + addParameter("iconWidth", findValue(iconWidth, Integer.class)); + } + if (iconHeight != null) { + addParameter("iconHeight", findValue(iconHeight, Integer.class)); + } + if (toggleDuration != null) { + addParameter("toggleDuration", findValue(toggleDuration, Integer.class)); + } + if (templateCssPath != null) { + addParameter("templateCssPath", findString(templateCssPath)); + } + if (href != null) + addParameter("href", findString(href)); + if (errorNotifyTopics != null) + addParameter("errorNotifyTopics", findString(errorNotifyTopics)); + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + + if (this.childrenIds != null) + addParameter("childrenIds", this.childrenIds); + } + + public void addChildrenId(String id) { + if (this.childrenIds == null) + this.childrenIds = new ArrayList(); + this.childrenIds.add(id); + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + public String getDefaultOpenTemplate() { + return OPEN_TEMPLATE; + } + + protected String getDefaultTemplate() { + return TEMPLATE; + } + + public String getToggle() { + return toggle; + } + + @StrutsTagAttribute(description="The toggle property (either 'explode' or 'fade')", defaultValue="fade") + public void setToggle(String toggle) { + this.toggle = toggle; + } + + @StrutsTagAttribute(description="Deprecated. Use 'selectedNotifyTopics' instead.") + public void setTreeSelectedTopic(String selectedNotifyTopic) { + this.selectedNotifyTopics = selectedNotifyTopic; + } + + @StrutsTagAttribute(description="Deprecated. Use 'expandedNotifyTopics' instead.") + public void setTreeExpandedTopics(String expandedNotifyTopic) { + this.expandedNotifyTopics = expandedNotifyTopic; + } + + @StrutsTagAttribute(description="Deprecated. Use 'collapsedNotifyTopics' instead.") + public void setTreeCollapsedTopics(String collapsedNotifyTopic) { + this.collapsedNotifyTopics = collapsedNotifyTopic; + } + + public String getRootNode() { + return rootNodeAttr; + } + + @StrutsTagAttribute(description="The rootNode property.") + public void setRootNode(String rootNode) { + this.rootNodeAttr = rootNode; + } + + public String getChildCollectionProperty() { + return childCollectionProperty; + } + + @StrutsTagAttribute(description="The childCollectionProperty property.") + public void setChildCollectionProperty(String childCollectionProperty) { + this.childCollectionProperty = childCollectionProperty; + } + + public String getNodeTitleProperty() { + return nodeTitleProperty; + } + + @StrutsTagAttribute(description="The nodeTitleProperty property.") + public void setNodeTitleProperty(String nodeTitleProperty) { + this.nodeTitleProperty = nodeTitleProperty; + } + + public String getNodeIdProperty() { + return nodeIdProperty; + } + + @StrutsTagAttribute(description="The nodeIdProperty property.") + public void setNodeIdProperty(String nodeIdProperty) { + this.nodeIdProperty = nodeIdProperty; + } + + @StrutsTagAttribute(description="The showRootGrid property (default true).") + public void setShowRootGrid(String showRootGrid) { + this.showRootGrid = showRootGrid; + } + + public String getShowRootGrid() { + return showRootGrid; + } + + public String getBlankIconSrc() { + return blankIconSrc; + } + + @StrutsTagAttribute(description="Blank icon image source.") + public void setBlankIconSrc(String blankIconSrc) { + this.blankIconSrc = blankIconSrc; + } + + public String getExpandIconSrcMinus() { + return expandIconSrcMinus; + } + + @StrutsTagAttribute(description="Expand icon (-) image source.") + public void setExpandIconSrcMinus(String expandIconSrcMinus) { + this.expandIconSrcMinus = expandIconSrcMinus; + } + + public String getExpandIconSrcPlus() { + return expandIconSrcPlus; + } + + @StrutsTagAttribute(description="Expand Icon (+) image source.") + public void setExpandIconSrcPlus(String expandIconSrcPlus) { + this.expandIconSrcPlus = expandIconSrcPlus; + } + + public String getGridIconSrcC() { + return gridIconSrcC; + } + + @StrutsTagAttribute(description="Image source for under child item child icons.") + public void setGridIconSrcC(String gridIconSrcC) { + this.gridIconSrcC = gridIconSrcC; + } + + public String getGridIconSrcL() { + return gridIconSrcL; + } + + + @StrutsTagAttribute(description=" Image source for last child grid.") + public void setGridIconSrcL(String gridIconSrcL) { + this.gridIconSrcL = gridIconSrcL; + } + + public String getGridIconSrcP() { + return gridIconSrcP; + } + + @StrutsTagAttribute(description="Image source for under parent item child icons.") + public void setGridIconSrcP(String gridIconSrcP) { + this.gridIconSrcP = gridIconSrcP; + } + + public String getGridIconSrcV() { + return gridIconSrcV; + } + + @StrutsTagAttribute(description="Image source for vertical line.") + public void setGridIconSrcV(String gridIconSrcV) { + this.gridIconSrcV = gridIconSrcV; + } + + public String getGridIconSrcX() { + return gridIconSrcX; + } + + @StrutsTagAttribute(description="Image source for grid for sole root item.") + public void setGridIconSrcX(String gridIconSrcX) { + this.gridIconSrcX = gridIconSrcX; + } + + public String getGridIconSrcY() { + return gridIconSrcY; + } + + @StrutsTagAttribute(description="Image source for grid for last root item.") + public void setGridIconSrcY(String gridIconSrcY) { + this.gridIconSrcY = gridIconSrcY; + } + + public String getIconHeight() { + return iconHeight; + } + + + @StrutsTagAttribute(description="Icon height", defaultValue="18px") + public void setIconHeight(String iconHeight) { + this.iconHeight = iconHeight; + } + + public String getIconWidth() { + return iconWidth; + } + + @StrutsTagAttribute(description="Icon width", defaultValue="19px") + public void setIconWidth(String iconWidth) { + this.iconWidth = iconWidth; + } + + + + public String getTemplateCssPath() { + return templateCssPath; + } + + @StrutsTagAttribute(description="Template css path", defaultValue="{contextPath}/struts/tree.css.") + public void setTemplateCssPath(String templateCssPath) { + this.templateCssPath = templateCssPath; + } + + public String getToggleDuration() { + return toggleDuration; + } + + @StrutsTagAttribute(description="Toggle duration in milliseconds", defaultValue="150") + public void setToggleDuration(String toggleDuration) { + this.toggleDuration = toggleDuration; + } + + public String getShowGrid() { + return showGrid; + } + + @StrutsTagAttribute(description="Show grid", type="Boolean", defaultValue="true") + public void setShowGrid(String showGrid) { + this.showGrid = showGrid; + } + + @StrutsTagAttribute(description="The css class to use for element") + public void setCssClass(String cssClass) { + super.setCssClass(cssClass); + } + + @StrutsTagAttribute(description="The css style to use for element") + public void setCssStyle(String cssStyle) { + super.setCssStyle(cssStyle); + } + + @StrutsTagAttribute(description="The id to use for the element") + public void setId(String id) { + super.setId(id); + } + + @StrutsTagAttribute(description="The name to set for element") + public void setName(String name) { + super.setName(name); + } + + @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + + " is collapsed. An object with a 'node' property will be passed as parameter to the topics.") + public void setCollapsedNotifyTopics(String collapsedNotifyTopics) { + this.collapsedNotifyTopics = collapsedNotifyTopics; + } + + @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + + " is expanded. An object with a 'node' property will be passed as parameter to the topics.") + public void setExpandedNotifyTopics(String expandedNotifyTopics) { + this.expandedNotifyTopics= expandedNotifyTopics; + } + + @StrutsTagAttribute(description="Comma separated lis of topics to be published when a node" + + " is selected. An object with a 'node' property will be passed as parameter to the topics.") + public void setSelectedNotifyTopics(String selectedNotifyTopics) { + this.selectedNotifyTopics = selectedNotifyTopics; + } + + @StrutsTagAttribute(description="Url used to load the list of children nodes for an specific node, whose id will be " + + "passed as a parameter named 'nodeId' (empty for root)") + public void setHref(String href) { + this.href = href; + } + + @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)." + + "Only valid if 'href' is set") + public void setErrorNotifyTopics(String errorNotifyTopics) { + this.errorNotifyTopics = errorNotifyTopics; + } +} + diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TreeNode.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TreeNode.java index 6404b2afb..06d41f764 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TreeNode.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/components/TreeNode.java @@ -1,136 +1,153 @@ -/* - * $Id: TreeNode.java 497654 2007-01-19 00:21:57Z rgielen $ - * - * 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.dojo.components; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.struts2.components.ClosingUIBean; -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; - -/** - * - * - * Renders a tree node within a tree widget with AJAX support.

- * - * Either of the following combinations should be used depending on if the tree - * is to be constrcted dynamically or statically.

- * - * Dynamically - *

    - *
  • id - id of this tree node
  • - *
  • title - label to be displayed for this tree node
  • - *
- * - * Statically - *
    - *
  • rootNode - the parent node of which this tree is derived from
  • - *
  • nodeIdProperty - property to obtained this current tree node's id
  • - *
  • nodeTitleProperty - property to obtained this current tree node's title
  • - *
  • childCollectionProperty - property that returnds this current tree node's children
  • - *
- * - * - * - *

Examples - * - *

- * 
- *
- * <-- statically -->
- * <s:tree id="..." label="...">
- *    <s:treenode id="..." label="..." />
- *    <s:treenode id="..." label="...">
- *        <s:treenode id="..." label="..." />
- *        <s:treenode id="..." label="..." />
- *    &;lt;/s:treenode>
- *    <s:treenode id="..." label="..." />
- * </s:tree>
- *
- * <-- dynamically -->
- * <s:tree
- *          id="..."
- *          rootNode="..."
- *          nodeIdProperty="..."
- *          nodeTitleProperty="..."
- *          childCollectionProperty="..." />
- *
- * 
- * 
- * - */ -@StrutsTag(name="treenode", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TreeNodeTag", description="Render a tree node within a tree widget.") -public class TreeNode extends ClosingUIBean { - private static final String TEMPLATE = "treenode-close"; - private static final String OPEN_TEMPLATE = "treenode"; - - public TreeNode(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { - super(stack, request, response); - } - - @Override - @StrutsTagSkipInheritance - public void setTheme(String theme) { - super.setTheme(theme); - } - - @Override - public String getTheme() { - return "ajax"; - } - - public String getDefaultOpenTemplate() { - return OPEN_TEMPLATE; - } - - protected String getDefaultTemplate() { - return TEMPLATE; - } - - @StrutsTagAttribute(description="Label expression used for rendering tree node label.", required=true) - public void setLabel(String label) { - super.setLabel(label); - } - - @StrutsTagAttribute(description="The css class to use for element") - public void setCssClass(String cssClass) { - super.setCssClass(cssClass); - } - - @StrutsTagAttribute(description="The css style to use for element") - public void setCssStyle(String cssStyle) { - super.setCssStyle(cssStyle); - } - - @StrutsTagAttribute(description="The id to use for the element") - public void setId(String id) { - super.setId(id); - } - - @StrutsTagAttribute(description="The name to set for element") - public void setName(String name) { - super.setName(name); - } -} +/* + * $Id: TreeNode.java 497654 2007-01-19 00:21:57Z rgielen $ + * + * 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.dojo.components; + +import java.util.Random; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.struts2.components.ClosingUIBean; +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; + +/** + * + * + * Renders a tree node within a tree widget with AJAX support.

+ * + * Either of the following combinations should be used depending on if the tree + * is to be constrcted dynamically or statically.

+ * + * Dynamically + *

    + *
  • id - id of this tree node
  • + *
  • title - label to be displayed for this tree node
  • + *
+ * + * Statically + *
    + *
  • rootNode - the parent node of which this tree is derived from
  • + *
  • nodeIdProperty - property to obtained this current tree node's id
  • + *
  • nodeTitleProperty - property to obtained this current tree node's title
  • + *
  • childCollectionProperty - property that returnds this current tree node's children
  • + *
+ * + * + * + *

Examples + * + *

+ * 
+ *
+ * <-- statically -->
+ * <s:tree id="..." label="...">
+ *    <s:treenode id="..." label="..." />
+ *    <s:treenode id="..." label="...">
+ *        <s:treenode id="..." label="..." />
+ *        <s:treenode id="..." label="..." />
+ *    &;lt;/s:treenode>
+ *    <s:treenode id="..." label="..." />
+ * </s:tree>
+ *
+ * <-- dynamically -->
+ * <s:tree
+ *          id="..."
+ *          rootNode="..."
+ *          nodeIdProperty="..."
+ *          nodeTitleProperty="..."
+ *          childCollectionProperty="..." />
+ *
+ * 
+ * 
+ * + */ +@StrutsTag(name="treenode", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.TreeNodeTag", description="Render a tree node within a tree widget.") +public class TreeNode extends ClosingUIBean { + private static final String TEMPLATE = "treenode-close"; + private static final String OPEN_TEMPLATE = "treenode"; + + public TreeNode(ValueStack stack, HttpServletRequest request, HttpServletResponse response) { + super(stack, request, response); + } + + @Override + @StrutsTagSkipInheritance + public void setTheme(String theme) { + super.setTheme(theme); + } + + @Override + public String getTheme() { + return "ajax"; + } + + public String getDefaultOpenTemplate() { + return OPEN_TEMPLATE; + } + + protected String getDefaultTemplate() { + return TEMPLATE; + } + + protected void evaluateExtraParams() { + super.evaluateExtraParams(); + + boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT); + addParameter("pushId", generateId); + if ((this.id == null || this.id.length() == 0) && generateId) { + Random random = new Random(); + this.id = "widget_" + Math.abs(random.nextInt()); + addParameter("id", this.id); + } + + Tree parentTree = (Tree) findAncestor(Tree.class); + parentTree.addChildrenId(this.id); + } + + @StrutsTagAttribute(description="Label expression used for rendering tree node label.", required=true) + public void setLabel(String label) { + super.setLabel(label); + } + + @StrutsTagAttribute(description="The css class to use for element") + public void setCssClass(String cssClass) { + super.setCssClass(cssClass); + } + + @StrutsTagAttribute(description="The css style to use for element") + public void setCssStyle(String cssStyle) { + super.setCssStyle(cssStyle); + } + + @StrutsTagAttribute(description="The id to use for the element") + public void setId(String id) { + super.setId(id); + } + + @StrutsTagAttribute(description="The name to set for element") + public void setName(String name) { + super.setName(name); + } +} diff --git a/plugins/dojo/src/main/java/org/apache/struts2/dojo/views/jsp/ui/HeadTag.java b/plugins/dojo/src/main/java/org/apache/struts2/dojo/views/jsp/ui/HeadTag.java index 67e35ec48..1b43e2938 100644 --- a/plugins/dojo/src/main/java/org/apache/struts2/dojo/views/jsp/ui/HeadTag.java +++ b/plugins/dojo/src/main/java/org/apache/struts2/dojo/views/jsp/ui/HeadTag.java @@ -42,6 +42,7 @@ public class HeadTag extends AbstractUITag { private String extraLocales; private String locale; private String cache; + private String parseContent; public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) { return new Head(stack, req, res); @@ -57,6 +58,7 @@ public class HeadTag extends AbstractUITag { head.setExtraLocales(extraLocales); head.setLocale(locale); head.setCache(cache); + head.setParseContent(parseContent); } public void setDebug(String debug) { @@ -82,4 +84,8 @@ public class HeadTag extends AbstractUITag { public void setCache(String cache) { this.cache = cache; } + + public void setParseContent(String parseContent) { + this.parseContent = parseContent; + } } diff --git a/plugins/dojo/src/main/resources/template/ajax/a-close.ftl b/plugins/dojo/src/main/resources/template/ajax/a-close.ftl index 7d3ab3f85..33248d53b 100644 --- a/plugins/dojo/src/main/resources/template/ajax/a-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/a-close.ftl @@ -21,3 +21,6 @@ */ --> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/autocompleter.ftl b/plugins/dojo/src/main/resources/template/ajax/autocompleter.ftl index a24319dfb..c9c57b4ec 100644 --- a/plugins/dojo/src/main/resources/template/ajax/autocompleter.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/autocompleter.ftl @@ -173,5 +173,8 @@ <#if parameters.label?if_exists != ""> <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" /> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/bind-close.ftl b/plugins/dojo/src/main/resources/template/ajax/bind-close.ftl index 332885dab..fdf57664f 100644 --- a/plugins/dojo/src/main/resources/template/ajax/bind-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/bind-close.ftl @@ -20,3 +20,6 @@ * under the License. */ --> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/datetimepicker.ftl b/plugins/dojo/src/main/resources/template/ajax/datetimepicker.ftl index 096e2d82c..b8b5b7e9d 100644 --- a/plugins/dojo/src/main/resources/template/ajax/datetimepicker.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/datetimepicker.ftl @@ -97,3 +97,6 @@ <#if parameters.label?if_exists != ""> <#include "/${parameters.templateDir}/xhtml/controlfooter.ftl" /> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/div-close.ftl b/plugins/dojo/src/main/resources/template/ajax/div-close.ftl index f11303870..867e944e2 100644 --- a/plugins/dojo/src/main/resources/template/ajax/div-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/div-close.ftl @@ -21,3 +21,6 @@ */ --> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/head.ftl b/plugins/dojo/src/main/resources/template/ajax/head.ftl index b99023e97..42ede8d09 100644 --- a/plugins/dojo/src/main/resources/template/ajax/head.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/head.ftl @@ -42,6 +42,8 @@ ] + ,parseWidgets : ${parameters.parseContent?string} + }; diff --git a/plugins/dojo/src/main/resources/template/ajax/submit.ftl b/plugins/dojo/src/main/resources/template/ajax/submit.ftl index 45f66b97d..2dabab36a 100644 --- a/plugins/dojo/src/main/resources/template/ajax/submit.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/submit.ftl @@ -93,4 +93,7 @@ <#else> <#t/> + +<#if parameters.pushId> + \ No newline at end of file diff --git a/plugins/dojo/src/main/resources/template/ajax/tab-close.ftl b/plugins/dojo/src/main/resources/template/ajax/tab-close.ftl index f11303870..867e944e2 100644 --- a/plugins/dojo/src/main/resources/template/ajax/tab-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/tab-close.ftl @@ -21,3 +21,6 @@ */ --> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/tabbedpanel-close.ftl b/plugins/dojo/src/main/resources/template/ajax/tabbedpanel-close.ftl index f11303870..867e944e2 100644 --- a/plugins/dojo/src/main/resources/template/ajax/tabbedpanel-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/tabbedpanel-close.ftl @@ -21,3 +21,6 @@ */ --> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/tree-close.ftl b/plugins/dojo/src/main/resources/template/ajax/tree-close.ftl index 7e8e69feb..f95ef3d33 100644 --- a/plugins/dojo/src/main/resources/template/ajax/tree-close.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/tree-close.ftl @@ -21,3 +21,16 @@ */ --> <#if parameters.label?exists> +<#if parameters.pushId> + + diff --git a/plugins/dojo/src/main/resources/template/ajax/tree.ftl b/plugins/dojo/src/main/resources/template/ajax/tree.ftl index 136acb873..640d70190 100644 --- a/plugins/dojo/src/main/resources/template/ajax/tree.ftl +++ b/plugins/dojo/src/main/resources/template/ajax/tree.ftl @@ -30,7 +30,9 @@ <#if parameters.selectedNotifyTopics?exists || parameters.expandedNotifyTopics?exists || parameters.collapsedNotifyTopics?exists> - selectedNotifyTopics="${parameters.selectedNotifyTopics?html}" diff --git a/plugins/dojo/src/profile/README b/plugins/dojo/src/profile/README index 7e9639ce3..86bb3ee57 100644 --- a/plugins/dojo/src/profile/README +++ b/plugins/dojo/src/profile/README @@ -1,8 +1,8 @@ To build the Struts Dojo profile: -1. Checkout Dojo from svn (${dojo} refers to root dir) +1. Checkout Dojo from svn (${dojo} refers to dojo's root dir) (make sure that ${dojo} is on the same folder as ${struts}) -2. Copy struts.profile.js tp ${dojo}/buildscripts/profiles +2. Copy struts.profile.js to ${dojo}/buildscripts/profiles 3. Copy /plugins/dojo/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css to ${dojo}/struts (Dojo build system doesn't resolve the relative paths that well in 0.4.2) diff --git a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AbstractTagTest.java b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AbstractTagTest.java index c33c69aa7..72ba0a684 100644 --- a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AbstractTagTest.java +++ b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AbstractTagTest.java @@ -35,6 +35,7 @@ import org.apache.struts2.dispatcher.Dispatcher; import org.apache.struts2.dispatcher.RequestMap; import org.apache.struts2.dispatcher.SessionMap; import org.apache.struts2.dojo.TestAction; +import org.apache.struts2.dojo.components.Head; import com.mockobjects.dynamic.Mock; import com.opensymphony.xwork2.Action; @@ -85,6 +86,7 @@ public abstract class AbstractTagTest extends StrutsTestCase { stack = ValueStackFactory.getFactory().createValueStack(); context = stack.getContext(); stack.push(action); + context.put(Head.PARSE_CONTENT, false); request = new StrutsMockHttpServletRequest(); request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); diff --git a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AutocompleterTest.java b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AutocompleterTest.java index cfed157a6..95c38ee74 100644 --- a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AutocompleterTest.java +++ b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/AutocompleterTest.java @@ -38,6 +38,7 @@ public class AutocompleterTest extends AbstractUITagTest { tag.setSearchType("b"); tag.setDisabled("c"); tag.setName("f"); + tag.setId("f"); tag.setValue("g"); tag.setIndicator("h"); tag.setKeyName("i"); @@ -70,6 +71,7 @@ public class AutocompleterTest extends AbstractUITagTest { tag.setSearchType("b"); tag.setDisabled("c"); tag.setName("f"); + tag.setId("f"); tag.setIconPath("i"); tag.setTemplateCssPath("j"); tag.setValueNotifyTopics("k"); diff --git a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/DivTest.java b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/DivTest.java index 7a13763a1..73d67110c 100644 --- a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/DivTest.java +++ b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/DivTest.java @@ -21,6 +21,7 @@ package org.apache.struts2.dojo.views.jsp.ui; import org.apache.struts2.dojo.TestAction; +import org.apache.struts2.dojo.components.Head; /** diff --git a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest.java b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest.java index d82c8fb1c..87486521c 100644 --- a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest.java +++ b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest.java @@ -40,6 +40,7 @@ public class HeadTagTest extends AbstractUITagTest { tag.setBaseRelativePath("/path"); tag.setLocale("es"); tag.setCache("true"); + tag.setParseContent("true"); tag.doStartTag(); tag.doEndTag(); diff --git a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/TabbedPanelTagTest.java b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/TabbedPanelTagTest.java index 6934c348b..5b20529ca 100644 --- a/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/TabbedPanelTagTest.java +++ b/plugins/dojo/src/test/java/org/apache/struts2/dojo/views/jsp/ui/TabbedPanelTagTest.java @@ -28,7 +28,7 @@ public class TabbedPanelTagTest extends AbstractUITagTest { public void testSimple() throws Exception { TabbedPanelTag tag = new TabbedPanelTag(); tag.setPageContext(pageContext); - + tag.setId("a"); tag.doStartTag(); tag.doEndTag(); diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-1.txt index 45803e396..4f0943082 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-1.txt @@ -23,3 +23,4 @@ transport="m" preload="true" /> + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-2.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-2.txt index fe2d7cd51..0fc7a9fd6 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-2.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Autocompleter-2.txt @@ -18,3 +18,4 @@ + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Bind-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Bind-1.txt index 983bfd1f4..0d5e70618 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Bind-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/Bind-1.txt @@ -25,4 +25,5 @@ "parseContent" : false }); }); - \ No newline at end of file + + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/DateTimePickerTagTest-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/DateTimePickerTagTest-1.txt index 922c669ef..be939ae60 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/DateTimePickerTagTest-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/DateTimePickerTagTest-1.txt @@ -14,4 +14,5 @@ valueNotifyTopics="k" saveFormat="rfc"> + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-1.txt index 51a71bf84..6223ced41 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-1.txt @@ -10,7 +10,8 @@ "a", "b", "c" - ] + ], + parseWidgets: true }; diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-2.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-2.txt index a551daff8..caa96ef04 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-2.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/HeadTagTest-2.txt @@ -1,32 +1,33 @@ - - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-1.txt index 1b3c8b625..c7f345b36 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-1.txt @@ -1,5 +1,7 @@
+ diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-2.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-2.txt index dfd41bb8f..e08d392e7 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-2.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-2.txt @@ -14,4 +14,5 @@ dojo.addOnLoad(function(){ });
-
\ No newline at end of file + + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-3.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-3.txt index fac0220f1..5bb814019 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-3.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/TabbedPanel-3.txt @@ -10,4 +10,5 @@ dojo.addOnLoad(function(){ });
-
\ No newline at end of file + + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/div-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/div-1.txt index 0f7c37bcf..5e0cb5161 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/div-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/div-1.txt @@ -25,3 +25,4 @@ transport="q" parseContent="false"> + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/href-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/href-1.txt index 51b020444..304fef26f 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/href-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/href-1.txt @@ -22,3 +22,4 @@ transport="o" parseContent="false"> + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-1.txt index 776d2a86b..4d66c0ce3 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-1.txt @@ -25,3 +25,4 @@ transport="p" parseContent="false" /> + diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-2.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-2.txt index 82072612f..6f571188c 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-2.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-2.txt @@ -17,4 +17,5 @@ indicator="l" scriptSeparation="true" value="i" - /> \ No newline at end of file + /> + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-3.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-3.txt index 158fce385..2f372efff 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-3.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/submit-ajax-3.txt @@ -20,4 +20,5 @@ handler="h" indicator="l" scriptSeparation="true" - /> \ No newline at end of file + /> + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-1.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-1.txt index 302cf16e2..c78830f7e 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-1.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-1.txt @@ -39,4 +39,9 @@ id="child3" title="Child 4"> - \ No newline at end of file + + \ No newline at end of file diff --git a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-2.txt b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-2.txt index a7a871bb3..325ad6433 100644 --- a/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-2.txt +++ b/plugins/dojo/src/test/resources/org/apache/struts2/dojo/views/jsp/ui/tree-2.txt @@ -61,4 +61,8 @@ - \ No newline at end of file + + \ No newline at end of file