Author: husted
Date: Wed Dec 27 13:26:44 2006
New Revision: 490569

URL: http://svn.apache.org/viewvc?view=rev&rev=490569
Log:
WW-1562 Apply patch submitted by Musachy Barros. Fixed on this patch:
* Added "loadOnTextChange"
* Added "loadMinimumCout"
* selected values are loaded if page is loaded again
* added "showDownArrow"

Added:
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css
Modified:
    
struts/struts2/trunk/apps/showcase/src/main/webapp/ajax/autocompleter/index.jsp
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Autocompleter.java
    
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AutocompleterTag.java
    struts/struts2/trunk/core/src/main/resources/META-INF/struts-tags.tld
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/Bind.js
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindAnchor.js
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindDiv.js
    
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js
    struts/struts2/trunk/core/src/main/resources/template/ajax/autocompleter.ftl
    
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AutocompleterTest.java
    
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-1.txt
    
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-2.txt

Modified: 
struts/struts2/trunk/apps/showcase/src/main/webapp/ajax/autocompleter/index.jsp
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/apps/showcase/src/main/webapp/ajax/autocompleter/index.jsp?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/apps/showcase/src/main/webapp/ajax/autocompleter/index.jsp 
(original)
+++ 
struts/struts2/trunk/apps/showcase/src/main/webapp/ajax/autocompleter/index.jsp 
Wed Dec 27 13:26:44 2006
@@ -11,11 +11,20 @@
 
 <body>
 
+
 <s:url id="jsonList" value="/JSONList.action"/>
 
-Using a JSON list returned from an action (href="/JSONList.action"), without 
autoComplete (autoComplete="false"), use indicator
+Using a JSON list returned from an action (href="/JSONList.action"), without 
autoComplete (autoComplete="false"), use indicator, search substring 
(searchType="substring")
+<br/>
+<s:autocompleter name="state" theme="ajax" indicator="indicator1" 
href="%{jsonList}" cssStyle="width: 200px;" autoComplete="false" 
searchType="substring"/>
+<img id="indicator1" 
src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading..." 
style="display:none"/>
+
+<br/>
+<br/>
+
+Reload on type (loadOnTextChange="true"), after 3 characters 
(loadMinimumCout="3", it is "3" by default), without the down arrow button 
(showDownArrow="false")
 <br/>
-<s:autocompleter name="state" theme="ajax" indicator="indicator" 
href="%{jsonList}" cssStyle="width: 200px;" autoComplete="false"/>
+<s:autocompleter theme="ajax" indicator="indicator" href="%{jsonList}" 
cssStyle="width: 200px;" autoComplete="false" loadOnTextChange="true" 
loadMinimumCount="3" showDownArrow="false"/>
 <img id="indicator" 
src="${pageContext.request.contextPath}/images/indicator.gif" alt="Loading..." 
style="display:none"/>
 
 <br/>
@@ -64,7 +73,7 @@
 <form id="selectForm">
   <p>Autocompleter 1 <s:autocompleter theme="simple" name="select" 
list="{'fruits','colors'}"  value="colors" notifyTopics="/Changed" 
forceValidOption="true" id="sel"/></p>
 </form>
-Autocompleter 2 <s:autocompleter theme="ajax" href="%{#autoex}" 
autoComplete="false" formId="selectForm" listenTopics="/Changed" 
notifyTopics="/OpsChanged" forceValidOption="true" id="ops"/>
+Autocompleter 2 <s:autocompleter theme="ajax" href="%{#autoex}" 
autoComplete="false" formId="selectForm" listenTopics="/Changed" 
forceValidOption="true" id="ops"/>
 
 <br/>
 <br/>

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Autocompleter.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Autocompleter.java?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Autocompleter.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/components/Autocompleter.java
 Wed Dec 27 13:26:44 2006
@@ -48,6 +48,10 @@
  *      <li>formId</li>
  *      <li>formFilter</li>
  *      <li>indicator</li>
+ *      <li>loadOnTextChange</li>
+ *      <li>loadMinimumCount</li>
+ *      <li>showDownArrow</li>
+ *      <li>searchType</li>
  * </ul>
  * 'dropdownWidth' width in pixels of the drodpdown, same as autocompleter's 
width by default<p/>
  * 'dropdownHeight' height in pixels of the drodown, 120 px by default<p/>
@@ -61,6 +65,10 @@
  * 'listenTopics' comma separated list of topics names, that will trigger a 
request
  * 'indicator' element to be shown while the request executing
  * 'showErrorTransportText': whether errors should be displayed (on 
'targets')<p/>
+ * 'loadOnTextChange' options will be reloaded everytime a character is typed 
on the textbox<p/>
+ * 'loadMinimumCount' minimum number of characters that will force the content 
to be loaded<p/>
+ * 'showDownError' show or hide the down arrow button
+ * 'searchType' how the search must be performed, options are: "startstring", 
"startword" and "substring"<p/>
  * 'notifyTopics' comma separated list of topics names, that will be 
published. Three parameters are passed:<p/>
  * <ul>
  *      <li>data: selected value when type='valuechanged'</li>
@@ -88,6 +96,9 @@
     protected String listenTopics;
     protected String notifyTopics;
     protected String indicator;
+    protected String loadOnTextChange;
+    protected String loadMinimumCount;
+    protected String showDownArrow;
 
     public Autocompleter(ValueStack stack, HttpServletRequest request,
             HttpServletResponse response) {
@@ -109,8 +120,11 @@
         if (forceValidOption != null)
             addParameter("forceValidOption", findValue(forceValidOption,
                     Boolean.class));
-        if (searchType != null)
-            addParameter("searchType", findString(searchType));
+        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)
@@ -135,6 +149,14 @@
           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);
         //get the key value
         if(name != null) {
             String keyNameExpr = "%{" + name + "Key}";
@@ -188,7 +210,7 @@
 
 
     /**
-     * set how the serach bust be preformed, optionas are: "startstring", 
"startword" and "substring"
+     * set how the search must be performed, options are: "startstring", 
"startword" and "substring"
      * @s.tagattribute required="false" default="stringstart" type="String"
      */
     public void setSearchType(String searchType) {
@@ -254,5 +276,29 @@
      */
     public void setIndicator(String indicator) {
         this.indicator = indicator;
+    }
+
+    /**
+     * Minimum number of characters that will force the content to be loaded
+     * @s.tagattribute required="false" type="Integer" default="3"
+     */
+    public void setLoadMinimumCount(String loadMinimumCount) {
+        this.loadMinimumCount = loadMinimumCount;
+    }
+
+    /**
+     * Options will be reloaded everytime a character is typed on the textbox.
+     * @s.tagattribute required="false" type="Boolean" default="false"
+     */
+    public void setLoadOnTextChange(String loadOnType) {
+        this.loadOnTextChange = loadOnType;
+    }
+
+    /**
+     * Show or hide the down arrow button
+     * @s.tagattribute required="false" type="Boolean" default="true"
+     */
+    public void setShowDownArrow(String showDownArrow) {
+        this.showDownArrow = showDownArrow;
     }
 }

Modified: 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AutocompleterTag.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AutocompleterTag.java?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AutocompleterTag.java
 (original)
+++ 
struts/struts2/trunk/core/src/main/java/org/apache/struts2/views/jsp/ui/AutocompleterTag.java
 Wed Dec 27 13:26:44 2006
@@ -47,6 +47,9 @@
     protected String listenTopics;
     protected String notifyTopics;
     protected String indicator;
+    protected String loadOnTextChange;
+    protected String loadMinimumCount;
+    protected String showDownArrow;
 
     public Component getBean(ValueStack stack, HttpServletRequest req, 
HttpServletResponse res) {
         return new Autocompleter(stack, req, res);
@@ -69,6 +72,9 @@
         autocompleter.setListenTopics(listenTopics);
         autocompleter.setNotifyTopics(notifyTopics);
         autocompleter.setIndicator(indicator);
+        autocompleter.setLoadMinimumCount(loadMinimumCount);
+        autocompleter.setLoadOnTextChange(loadOnTextChange);
+        autocompleter.setShowDownArrow(showDownArrow);
     }
 
     public void setAutoComplete(String autoComplete) {
@@ -122,4 +128,21 @@
     public void setIndicator(String indicator) {
         this.indicator = indicator;
     }
+
+    public void setLoadMinimumCount(String loadMinimumCount) {
+        this.loadMinimumCount = loadMinimumCount;
+    }
+
+    public String getLoadMinimumCount() {
+        return loadMinimumCount;
+    }
+
+    public void setLoadOnTextChange(String loadOnTextChange) {
+        this.loadOnTextChange = loadOnTextChange;
+    }
+
+    public void setShowDownArrow(String showDownArrow) {
+        this.showDownArrow = showDownArrow;
+    }
+
 }

Modified: struts/struts2/trunk/core/src/main/resources/META-INF/struts-tags.tld
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/META-INF/struts-tags.tld?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- struts/struts2/trunk/core/src/main/resources/META-INF/struts-tags.tld 
(original)
+++ struts/struts2/trunk/core/src/main/resources/META-INF/struts-tags.tld Wed 
Dec 27 13:26:44 2006
@@ -2886,6 +2886,30 @@
             <description><![CDATA[Id of element that will be show while doing 
the request]]></description>
 
         </attribute>
+        <attribute>
+            <name>loadOnTextChange</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+
+            <description><![CDATA[Reload options when text changes on the 
textbox (false by default)]]></description>
+
+        </attribute>
+        <attribute>
+            <name>loadMinimumCount</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+
+            <description><![CDATA[Minimum number of characters that will force 
the content to be loaded (3 by default)]]></description>
+
+        </attribute>
+        <attribute>
+            <name>showDownArrow</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+
+            <description><![CDATA[Show or hide the down arrow button (true by 
default)]]></description>
+
+        </attribute>
            <attribute>
             <name>autoComplete</name>
             <required>false</required>
@@ -2977,7 +3001,15 @@
             <description><![CDATA[The URL to call to obtain the 
content]]></description>
 
         </attribute>
-       <attribute>
+        <attribute>
+            <name>searchType</name>
+            <required>false</required>
+            <rtexprvalue>true</rtexprvalue>
+
+            <description><![CDATA[how the search must be performed, options 
are: "startstring" (default), "startword" and "substring"]]></description>
+
+        </attribute>
+        <attribute>
             <name>list</name>
             <required>false</required>
             <rtexprvalue>true</rtexprvalue>

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/src/widget/ComboBox.js
 Wed Dec 27 13:26:44 2006
@@ -98,7 +98,7 @@
                                        var text = opts[x].textContent || 
opts[x].innerText || opts[x].innerHTML;
                                        var keyValArr = [String(text), 
String(opts[x].value)];
                                        data.push(keyValArr);
-                                       if(opts[x].selected){ 
+                                       if(opts[x].selected){
                                                cbox.setAllValues(keyValArr[0], 
keyValArr[1]);
                                        }
                                }
@@ -110,7 +110,7 @@
        this.getData = function(/*String*/ url){
                dojo.io.bind({
                        url: url,
-                       load: dojo.lang.hitch(this, function(type, data, evt){ 
+                       load: dojo.lang.hitch(this, function(type, data, evt){
                                if(!dojo.lang.isArray(data)){
                                        var arrData = [];
                                        for(var key in data){
@@ -212,7 +212,7 @@
                // populate this.data and initialize lookup structures
                this.data = pdata;
        };
-       
+
        if(dataPairs){
                this.setData(dataPairs);
        }
@@ -224,11 +224,11 @@
        {
                // Applies to any renderer
                isContainer: false,
-       
+
                forceValidOption: false,
-               searchType: "stringstart",
+               searchType: "STARTSTRING",
                dataProvider: null,
-       
+
                startSearch: function(/*String*/ searchString){},
                selectNextResult: function(){},
                selectPrevResult: function(){},
@@ -248,11 +248,11 @@
                dataUrl: "",
                fadeTime: 200,
                disabled: false,
-               // maxListLength limits list to X visible rows, scroll on rest 
-               maxListLength: 8, 
+               // maxListLength limits list to X visible rows, scroll on rest
+               maxListLength: 8,
                // mode can also be "remote" for JSON-returning live search or 
"html" for
                // dumber live search
-               mode: "local", 
+               mode: "local",
                selectedResult: null,
                _highlighted_option: null,
                _prev_key_backspace: false,
@@ -285,7 +285,7 @@
                getValue: function(){
                        return this.comboBoxValue.value;
                },
-       
+
                getState: function(){
                        return {value: this.getValue()};
                },
@@ -296,15 +296,15 @@
 
                enable:function(){
                        this.disabled=false;
-                       this.isEnabled = true; 
+                       this.isEnabled = true;
                        this.textInputNode.removeAttribute("disabled");
                },
- 
+
                disable: function(){
-                       this.disabled = true; 
+                       this.disabled = true;
                        this.isEnabled = false;
-                       this.textInputNode.setAttribute("disabled",true); 
-               }, 
+                       this.textInputNode.setAttribute("disabled",true);
+               },
 
                getCaretPos: function(/*DomNode*/ element){
                        // khtml 3.5.2 has selection* methods as does webkit 
nightlies from 2005-06-22
@@ -329,7 +329,7 @@
                                } catch (e){
                                        return 0; // If focus has shifted, 0 is 
fine for caret pos.
                                }
-                               
+
                        }
                },
 
@@ -398,7 +398,7 @@
                                        if(!this.autoComplete && 
this.popupWidget.isShowingNow && this._highlighted_option){
                                                
dojo.event.browser.stopEvent(evt);
                                                this.selectOption({ 'target': 
this._highlighted_option, 'noHide': false});
-       
+
                                                // put caret last
                                                
this.setSelectedRange(this.textInputNode, this.textInputNode.value.length, 
null);
                                        }else{
@@ -452,14 +452,14 @@
                        if(doSearch){
                                // if we have gotten this far we dont want to 
keep our highlight
                                this.blurOptionNode();
-       
+
                                // need to wait a tad before start search so 
that the event bubbles through DOM and we have value visible
                                this.searchTimer = 
setTimeout(dojo.lang.hitch(this, this.startSearchFromInput), this.searchDelay);
                        }
                },
 
-               // When inputting characters using an input method, such as 
Asian  
-               // languages, it will generate this event instead of onKeyDown 
event 
+               // When inputting characters using an input method, such as 
Asian
+               // languages, it will generate this event instead of onKeyDown 
event
                compositionEnd: function(/*Event*/ evt){
                        evt.key = evt.keyCode;
                        this._handleKeyEvents(evt);
@@ -543,9 +543,9 @@
                        // For inlining a table we need browser specific CSS
                        dojo.html.applyBrowserClass(this.domNode);
 
-                       var source = this.getFragNodeRef(frag); 
-                       if (! this.name && source.name){ this.name = 
source.name; } 
-                       this.comboBoxValue.name = this.name; 
+                       var source = this.getFragNodeRef(frag);
+                       if (! this.name && source.name){ this.name = 
source.name; }
+                       this.comboBoxValue.name = this.name;
                        this.comboBoxSelectionValue.name = 
this.name+"_selected";
 
                        /* different nodes get different parts of the style */
@@ -568,7 +568,7 @@
                        this.dataProvider = new dpClass();
                        this.dataProvider.init(this, this.getFragNodeRef(frag));
 
-                       this.popupWidget = new 
dojo.widget.createWidget("PopupContainer", 
+                       this.popupWidget = new 
dojo.widget.createWidget("PopupContainer",
                                {toggle: this.dropdownToggle, toggleDuration: 
this.toggleDuration});
                        dojo.event.connect(this, 'destroy', this.popupWidget, 
'destroy');
                        this.optionsListNode = this.popupWidget.domNode;
@@ -577,7 +577,7 @@
                        dojo.event.connect(this.optionsListNode, 'onclick', 
this, 'selectOption');
                        dojo.event.connect(this.optionsListNode, 'onmouseover', 
this, '_onMouseOver');
                        dojo.event.connect(this.optionsListNode, 'onmouseout', 
this, '_onMouseOut');
-                       
+
                        dojo.event.connect(this.optionsListNode, "onmouseover", 
this, "itemMouseOver");
                        dojo.event.connect(this.optionsListNode, "onmouseout", 
this, "itemMouseOut");
                },
@@ -648,7 +648,7 @@
                                this.blurTimer = dojo.lang.setTimeout(this, 
"checkBlurred", millisec);
                        }
                },
-       
+
                // these 2 are needed in IE and Safari as inputTextNode loses 
focus when scrolling optionslist
                _onMouseOver: function(/*Event*/ evt){
                        if(!this._mouseover_list){
@@ -726,7 +726,7 @@
 
                        if(!dojo.html.isDescendantOf(evt.target, 
this.optionsListNode)){
                                // handle autocompletion where the the user has 
hit ENTER or TAB
-       
+
                                // if the input is empty do nothing
                                if(!this.textInputNode.value.length){
                                        return;
@@ -739,7 +739,7 @@
                                }
                                // otherwise the user has accepted the 
autocompleted value
                        }else{
-                               tgt = evt.target; 
+                               tgt = evt.target;
                        }
 
                        
while((tgt.nodeType!=1)||(!tgt.getAttribute("resultName"))){
@@ -790,7 +790,7 @@
                                                height = visibleCount * 
dojo.html.getMarginBox(childs[0]).height +"px";
                                        }
                                        width = 
(dojo.html.getMarginBox(this.domNode).width-2)+"px";
-                                       
+
                                }
                                this.popupWidget.open(this.domNode, this, 
this.downArrowNode);
                        }else{
@@ -828,7 +828,7 @@
                        dojo.event.connect(this.dataProvider, 
"provideSearchResults", this, "openResultList");
                        dojo.event.connect(this.textInputNode, "onblur", this, 
"onBlurInput");
                        dojo.event.connect(this.textInputNode, "onfocus", this, 
"onFocusInput");
-                       if (this.disabled){ 
+                       if (this.disabled){
                                this.disable();
                        }
                        var s = 
dojo.widget.html.stabile.getState(this.widgetId);

Added: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css?view=auto&rev=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css
 (added)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/ComboBox.css
 Wed Dec 27 13:26:44 2006
@@ -0,0 +1,68 @@
+.dojoComboBoxOuter {
+       border: 0px !important;
+       margin: 0px !important;
+       padding: 0px !important;
+       background: transparent !important;
+       white-space: nowrap !important;
+}
+
+.dojoComboBox {
+       border: 1px inset #afafaf;
+       margin: 0px;
+       padding: 0px;
+       vertical-align: middle !important;
+       float: none !important;
+       position: static !important;
+       display: inline;
+}
+
+/* the input box */
+input.dojoComboBox {
+       border-right-width: 1px !important;
+       margin-right: 0px !important;
+       padding-right: 0px !important;
+}
+
+/* the down arrow */
+img.dojoComboBox {
+       border-left-width: 0px !important;
+       padding-left: 0px !important;
+       margin-left: 0px !important;
+}
+
+/* IE vertical-alignment calculations can be off by +-1 but these margins are 
collapsed away */
+.dj_ie img.dojoComboBox {
+       margin-top: 1px;
+       margin-bottom: 1px;
+}
+
+/* the drop down */
+.dojoComboBoxOptions {
+       font-family: Verdana, Helvetica, Garamond, sans-serif;
+       /* font-size: 0.7em; */
+       background-color: white;
+       border: 1px solid #afafaf;
+       position: absolute;
+       z-index: 1000;
+       overflow: auto;
+       cursor: default;
+}
+
+.dojoComboBoxItem {
+       padding-left: 2px;
+       padding-top: 2px;
+       margin: 0px;
+}
+
+.dojoComboBoxItemEven {
+       background-color: #f4f4f4;
+}
+
+.dojoComboBoxItemOdd {
+       background-color: white;
+}
+
+.dojoComboBoxItemHighlight {
+       background-color: #63709A;
+       color: white;
+}

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/Bind.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/Bind.js?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/Bind.js
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/Bind.js
 Wed Dec 27 13:26:44 2006
@@ -17,6 +17,7 @@
   loadingText : "Loading...",
   errorText : "",
   showError : true,
+  showLoading : true,
 
   //pub/sub events
   listenTopics : "",
@@ -35,14 +36,14 @@
   indicator : "",
 
   parseContent : true,
-
   postCreate : function() {
+    var self = this;
+
     //attach listeners
     if(!dojo.string.isBlank(this.listenTopics)) {
       this.log("Listening to " + this.listenTopics + " to refresh");
       var topics = this.listenTopics.split(",");
       if(topics) {
-        var self = this;
         if(topics) {
           if(topics) {
             dojo.lang.forEach(topics, function(topic){
@@ -61,15 +62,29 @@
       //split targets
       this.targetsArray = this.targets.split(",");
     }
+
     if(!dojo.string.isBlank(this.event)) {
-      dojo.event.connect(this.domNode, this.event, this, "reloadContents");
+      dojo.event.connect(this.domNode, this.event, function(evt) {
+        evt.preventDefault();
+        evt.stopPropagation();
+        self.reloadContents();
+      });
     }
-    if(dojo.string.isBlank(this.href)) {
-      this.formNode = dojo.string.isBlank(this.formId) ? 
dojo.dom.getFirstAncestorByTag(this.domNode, "form") : dojo.byId(this.formId);
-      this.href = this.formNode.action;
+
+    if(dojo.string.isBlank(this.href) && dojo.string.isBlank(this.formId)) {
+      //no href and no formId, we must be inside a form
+      this.formNode = dojo.dom.getFirstAncestorByTag(this.domNode, "form");
     } else {
       this.formNode = dojo.byId(this.formId);
     }
+
+    if(this.formNode && dojo.string.isBlank(this.href)) {
+      this.href = this.formNode.action;
+    }
+
+    if(!dojo.string.isBlank(this.formId)) {
+      this.formNode = dojo.byId(this.formId);
+    }
   },
 
   log : function(text) {
@@ -81,10 +96,10 @@
       var self = this;
          var xmlParser = new dojo.xml.Parse();
       dojo.lang.forEach(this.targetsArray, function(target) {
-
         var node = dojo.byId(target);
         node.innerHTML = text;
-        if(self.parseContent){
+
+        if(self.parseContent && text != self.loadingText){
           var frag  = xmlParser.parseElement(node, null, true);
           dojo.widget.getParser().createSubComponents(frag, 
dojo.widget.byId(target));
                }
@@ -131,10 +146,13 @@
 
   notify : function(data, type, e) {
     if(this.notifyTopicsArray) {
+      var self = this;
       dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
         try {
-          dojo.event.topic.publish(topic, data, type, null);
-        } catch(e){}
+          dojo.event.topic.publish(topic, data, type, e);
+        } catch(ex){
+                 self.log(ex);
+        }
       });
     }
   },
@@ -147,12 +165,13 @@
 
       eval(this.beforeLoading);
     }
-    if(!dojo.string.isBlank(this.loadingText)) {
+    if(this.showLoading && !dojo.string.isBlank(this.loadingText)) {
       event.text = this.loadingText;
     }
   },
 
-  reloadContents : function() {
+  reloadContents : function(evt) {
+
     if(!dojo.string.isBlank(this.handler)) {
       //use custom handler
       this.log("Invoking handler: " + this.handler);
@@ -169,14 +188,39 @@
         eval(this.beforeLoading);
       }
 
-      //show indicator
-      dojo.html.show(this.indicator);
       try {
           var self = this;
-          this.notify(this.widgetId, "before", {});
-          this.setContent(this.loadingText);
+          var request = {cancel: false};
+          this.notify(this.widgetId, "before", request);
+          if(request.cancel) {
+            this.log("Request canceled");
+            return;
+          }
+
+          //if the href is null, we still call the "beforeLoading"
+          // and publish the notigy topics
+          if(dojo.string.isBlank(this.href)) {
+            return;
+          }
+
+          //if there is a parent form, and it has a "onsubmit"
+          //execute it, validation is usually there
+          if(this.formNode && this.formNode.onsubmit != null) {
+            var makeRequest = this.formNode.onsubmit.call(evt);
+            if(makeRequest != null && !makeRequest) {
+              this.log("Request canceled by 'onsubmit' of the form");
+              return;
+            }
+          }
+
+          //show indicator
+          dojo.html.show(this.indicator);
+                 if(this.showLoading) {
+            this.setContent(this.loadingText);
+          }
+
           dojo.io.bind({
-            url: self.href,
+            url: this.href,
             useCache: false,
             preventCache: true,
             formNode: self.formNode,

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindAnchor.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindAnchor.js?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindAnchor.js
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindAnchor.js
 Wed Dec 27 13:26:44 2006
@@ -12,9 +12,10 @@
   event: "onclick",
 
   postCreate : function() {
-     this.domNode.href = "#";
      struts.widget.BindAnchor.superclass.postCreate.apply(this);
+     this.domNode.href = "#";
   }
 });
+
 
 

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindDiv.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindDiv.js?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindDiv.js
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/BindDiv.js
 Wed Dec 27 13:26:44 2006
@@ -25,7 +25,9 @@
 
     //messages
     loadingText : "Loading...",
+    showLoading : true,
     errorText : "",
+    showError : true,
 
     //pub/sub events
     listenTopics : "",
@@ -42,7 +44,6 @@
     formFilter : "",
     firstTime : true,
 
-    showError : true,
     indicator: "",
 
        //make dojo process the content
@@ -56,7 +57,11 @@
           return;
         }
       }
-      if(!dojo.string.isBlank(this.loadingText)) {
+      if(!this.showLoading) {
+        event.returnValue = false;
+        return;
+      }
+      if(this.showLoading && !dojo.string.isBlank(this.loadingText)) {
         event.text = this.loadingText;
       }
     },
@@ -85,10 +90,13 @@
 
     notify : function(data, type, e) {
       if(this.notifyTopicsArray) {
+        var self = this;
         dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
           try {
-            dojo.event.topic.publish(topic, data, type, null);
-          } catch(e){}
+            dojo.event.topic.publish(topic, data, type, e);
+          } catch(ex) {
+            self.log(ex);
+          }
         });
       }
     },
@@ -129,7 +137,6 @@
 
       //start the timer
       if(this.autoStart) {
-        this.log("autostarting");
         //start after delay
         if(this.delay > 0) {
           if(this.updateFreq > 0) {
@@ -185,10 +192,16 @@
           return;
         }
       }
+
+      var request = {cancel: false};
+      this.notify(this.widgetId, "before", request);
+      if(request.cancel) {
+        return;
+      }
+
       //show indicator
       dojo.html.show(this.indicator);
 
-      this.notify(this.widgetId, "before", {});
       this._handleDefaults("Loading...", "onDownloadStart");
       var self = this;
       dojo.io.bind({

Modified: 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js
 (original)
+++ 
struts/struts2/trunk/core/src/main/resources/org/apache/struts2/static/dojo/struts/widget/ComboBox.js
 Wed Dec 27 13:26:44 2006
@@ -198,6 +198,9 @@
   visibleDownArrow : true,
   fadeTime : 100,
 
+  //dojo has "stringstart" which is invalid
+  searchType: "STARTSTRING",
+
   templateCssPath: dojo.uri.dojoUri("struts/ComboBox.css"),
   //from Dojo's  ComboBox
   showResultList: function() {
@@ -258,10 +261,12 @@
             var i = text.toLowerCase().indexOf(typedText.toLowerCase());
             if(i >= 0) {
                 var pre = text.substring(0, i);
-                var matched = text.substring(i, typedText.length);
+                var matched = text.substring(i, i + typedText.length);
                 var post = text.substring(i + typedText.length);
 
-                td.appendChild(document.createTextNode(pre));
+                if(!dojo.string.isBlank(pre)) {
+                  td.appendChild(document.createTextNode(pre));
+                }
                 var boldNode = document.createElement("b");
                 td.appendChild(boldNode);
                 boldNode.appendChild(document.createTextNode(matched));
@@ -290,7 +295,12 @@
       var topics = this.listenTopics.split(",");
       for(var i = 0; i < topics.length; i++) {
         dojo.event.topic.subscribe(topics[i], function() {
-          self.notify(this.widgetId, "before", {});
+          var request = {cancel: false};
+             self.notify(this.widgetId, "before", request);
+             if(request.cancel) {
+               return;
+             }
+          self.clearValues();
           self.dataProvider.getData(self.dataUrl);
         });
       }
@@ -312,6 +322,11 @@
     if(!this.visibleDownArrow) {
       dojo.html.hide(this.downArrowNode);
     }
+
+    //search type
+    if(!dojo.string.isBlank(this.searchType)) {
+      this.dataProvider.searchType = this.searchType.toUpperCase();
+    }
   },
 
   clearValues : function() {
@@ -328,8 +343,10 @@
     if(this.notifyTopicsArray) {
       dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
         try {
-          dojo.event.topic.publish(topic, data, type, null);
-        } catch(e){}
+          dojo.event.topic.publish(topic, data, type, e);
+        } catch(ex) {
+          dojo.debug(ex);
+        }
       });
     }
   },
@@ -339,13 +356,15 @@
     if(this.loadOnType) {
        if(searchStr.length >= this.loadMinimum) {
            var nuHref = this.dataUrl + (this.dataUrl.indexOf("?") > -1 ? "&" : 
"?");
-                       nuHref += this.name + '=' + searchStr;
-                       this.dataProvider.getData(nuHref);
-                       this.startSearch(searchStr);
-       }
+               nuHref += this.name + '=' + searchStr;
+               this.dataProvider.getData(nuHref);
+               this.startSearch(searchStr);
+       } else {
+           this.hideResultList();
+        }
     }
     else {
-               this.startSearch(searchStr);
+         this.startSearch(searchStr);
        }
   }
 });

Modified: 
struts/struts2/trunk/core/src/main/resources/template/ajax/autocompleter.ftl
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/main/resources/template/ajax/autocompleter.ftl?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/main/resources/template/ajax/autocompleter.ftl 
(original)
+++ 
struts/struts2/trunk/core/src/main/resources/template/ajax/autocompleter.ftl 
Wed Dec 27 13:26:44 2006
@@ -15,7 +15,7 @@
  forceValidOption="${parameters.forceValidOption?string?html}"<#rt/>
 </#if>
 <#if parameters.searchType?if_exists != "">
- searchType="${parameters.searchType}"<#rt/>
+ searchType="${parameters.searchType?html}"<#rt/>
 </#if>
 <#if parameters.autoComplete?exists>
  autoComplete="${parameters.autoComplete?string?html}"<#rt/>
@@ -67,6 +67,15 @@
 </#if>
 <#if parameters.indicator?if_exists != "">
  indicator="${parameters.indicator?html}"<#rt/>
+</#if>
+<#if parameters.loadOnTextChange?default(false)>
+ loadOnType="${parameters.loadOnTextChange?string?html}"<#rt/>
+</#if>
+<#if parameters.loadMinimumCount?exists>
+ loadMinimum="${parameters.loadMinimumCount?c}"<#rt/>
+</#if>
+<#if parameters.showDownArrow?exists>
+ visibleDownArrow="${parameters.showDownArrow?string?html}"<#rt/>
 </#if>
 <#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
 >

Modified: 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AutocompleterTest.java
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AutocompleterTest.java?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AutocompleterTest.java
 (original)
+++ 
struts/struts2/trunk/core/src/test/java/org/apache/struts2/views/jsp/ui/AutocompleterTest.java
 Wed Dec 27 13:26:44 2006
@@ -23,6 +23,9 @@
         tag.setName("f");
         tag.setValue("g");
         tag.setIndicator("h");
+        tag.setLoadOnTextChange("true");
+        tag.setLoadMinimumCount("3");
+        tag.setShowDownArrow("false");
         tag.doStartTag();
         tag.doEndTag();
 

Modified: 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-1.txt
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-1.txt?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-1.txt
 (original)
+++ 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-1.txt
 Wed Dec 27 13:26:44 2006
@@ -3,11 +3,14 @@
  id="f"
  dataUrl="a"
  forceValidOption="false"
- searchType="b"
+ searchType="B"
  autoComplete="true"
  searchDelay="100"
  dropdownWidth="10"
  dropdownHeight="10"
  name="f"
  initialValue="g"
-indicator="h">
+ indicator="h"
+ loadOnType="true"
+ loadMinimum="3"
+ visibleDownArrow="false">

Modified: 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-2.txt
URL: 
http://svn.apache.org/viewvc/struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-2.txt?view=diff&rev=490569&r1=490568&r2=490569
==============================================================================
--- 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-2.txt
 (original)
+++ 
struts/struts2/trunk/core/src/test/resources/org/apache/struts2/views/jsp/ui/Autocompleter-2.txt
 Wed Dec 27 13:26:44 2006
@@ -3,7 +3,7 @@
  id="f"
  dataUrl="a"
  forceValidOption="false"
- searchType="b"
+ searchType="B"
  autoComplete="true"
  searchDelay="100"
  dropdownWidth="10"


Reply via email to