mirror of
https://github.com/apache/struts.git
synced 2026-08-11 09:36:57 +00:00
Fix autocompleter bug when reading data as a field of an object from the JSON returned from action
git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@544985 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -38,18 +38,11 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
* <p>1. If the response is an array, assume that it contains 2-dimension array elements, like:
|
||||
* <pre>
|
||||
* [
|
||||
* ["Text1", "Value1"],
|
||||
* ["Text2", "Value2"]
|
||||
* ["Alabama", "AL"],
|
||||
* ["Alaska", "AK"]
|
||||
* ]
|
||||
* </pre>
|
||||
* <p>2. If the response is a map, use it (recommended as it is the easiest one to generate):
|
||||
* <pre>
|
||||
* {
|
||||
* "Alabama" : "AL",
|
||||
* "Alaska" : "AL"
|
||||
* }
|
||||
* </pre>
|
||||
* <p>3. If a value is specified in the "dataFieldName" attribute, and the response has a field with that
|
||||
* <p>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"):</p>
|
||||
* <pre>
|
||||
@@ -65,11 +58,12 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
* {
|
||||
* "state" : {
|
||||
* "Alabama" : "AL",
|
||||
* "Alaska" : "AK"
|
||||
* "Alaska" : "AK"
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p>4. If there is a field that starts with the value specified on the "name" attribute, assume
|
||||
* </pre>
|
||||
* <p>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"):</p>
|
||||
* <pre>
|
||||
* {
|
||||
@@ -79,14 +73,20 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
* ]
|
||||
* }
|
||||
* </pre>
|
||||
* <p>5. Use first array that is found, like:<p>
|
||||
* <p>4. Use first array that is found, like:<p>
|
||||
* <pre>
|
||||
* {
|
||||
* "anything" : [
|
||||
* ["Text1", "Value1"],
|
||||
* ["Text2", "Value2"]
|
||||
* ["Alabama", "AL"],
|
||||
* ["Alaska", "AK"]
|
||||
* ]
|
||||
* }
|
||||
* <p>5. If the response is a map, use it (recommended as it is the easiest one to generate):
|
||||
* <pre>
|
||||
* {
|
||||
* "Alabama" : "AL",
|
||||
* "Alaska" : "AK"
|
||||
* }
|
||||
* </pre>
|
||||
* <!-- END SNIPPET: javadoc -->
|
||||
* <p>Examples</p>
|
||||
@@ -153,11 +153,73 @@ import com.opensymphony.xwork2.util.ValueStack;
|
||||
* autoCompleter.setSelectedKey("AL");
|
||||
*
|
||||
* //value (key will be set to "AL" and value to "Alabama")
|
||||
* autoCompleter.setSelectedValue("Alabama");
|
||||
* autoCompleter.setAllValues("AL", "Alabama");
|
||||
* }
|
||||
* </script>
|
||||
* </pre>
|
||||
* <!-- START SNIPPET: example5 -->
|
||||
*
|
||||
* <!-- START SNIPPET: example6 -->
|
||||
* <p>Using beforeNotifyTopics:</p>
|
||||
* <pre>
|
||||
* <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} />
|
||||
* </pre>
|
||||
* <!-- END SNIPPET: example6 -->
|
||||
*
|
||||
* <!-- START SNIPPET: example7 -->
|
||||
* <p>Using afterNotifyTopics:</p>
|
||||
* <pre>
|
||||
* <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}" />
|
||||
* </pre>
|
||||
* <!-- END SNIPPET: example7 -->
|
||||
*
|
||||
* <!-- START SNIPPET: example8-->
|
||||
* <p>Using errorNotifyTopics:</p>
|
||||
* <pre>
|
||||
* <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}" />
|
||||
* </pre>
|
||||
* <!-- END SNIPPET: example8 -->
|
||||
*
|
||||
* <!-- START SNIPPET: example9 -->
|
||||
* <p>Using valueNotifyTopics and indicator:</p>
|
||||
* <pre>
|
||||
* <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>
|
||||
* <pre>
|
||||
* <!-- END SNIPPET: example9 -->
|
||||
*/
|
||||
@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 {
|
||||
|
||||
+20
-35
@@ -34,12 +34,13 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
|
||||
//if notifyTopics is published on the first request (onload)
|
||||
//the value of listeners will be reset
|
||||
if(!this.firstRequest) {
|
||||
this.firstRequest = false;
|
||||
if(!this.firstRequest || type == "error") {
|
||||
this.cbox.notify.apply(this.cbox, [data, type, evt]);
|
||||
}
|
||||
|
||||
this.firstRequest = false;
|
||||
var arrData = null;
|
||||
var dataByName = data[this.cbox.dataFieldName];
|
||||
var dataByName = data[dojo.string.isBlank(this.cbox.dataFieldName) ? this.cbox.name : this.cbox.dataFieldName];
|
||||
if(!dojo.lang.isArray(data)) {
|
||||
//if there is a dataFieldName, take it
|
||||
if(dataByName) {
|
||||
@@ -50,7 +51,7 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
//it is an object, treat it like a map
|
||||
arrData = [];
|
||||
for(var key in dataByName){
|
||||
arrData.push([dataByName[key], key]);
|
||||
arrData.push([key, dataByName[key]]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -64,7 +65,7 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
} else {
|
||||
//if nathing else is found, we will use values in this
|
||||
//object as the data
|
||||
tmpArrData.push([data[key], key]);
|
||||
tmpArrData.push([key, data[key]]);
|
||||
}
|
||||
//grab the first array found, we will use it if nothing else
|
||||
//is found
|
||||
@@ -413,12 +414,13 @@ dojo.widget.defineWidget(
|
||||
},
|
||||
|
||||
notify : function(data, type, e) {
|
||||
var self = this;
|
||||
//general topics
|
||||
if(this.notifyTopicsArray) {
|
||||
var self = this;
|
||||
dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
|
||||
try {
|
||||
dojo.event.topic.publish(topic, data, type, e);
|
||||
} catch(ex) {
|
||||
dojo.event.topic.publish(topic, data, type, e, self);
|
||||
} catch(ex){
|
||||
self.log(ex);
|
||||
}
|
||||
});
|
||||
@@ -428,28 +430,26 @@ dojo.widget.defineWidget(
|
||||
var topicsArray = null;
|
||||
switch(type) {
|
||||
case "before":
|
||||
topicsArray = this.beforeNotifyTopicsArray;
|
||||
this.notifyTo(this.beforeNotifyTopicsArray, [e, this]);
|
||||
break;
|
||||
case "load":
|
||||
topicsArray = this.afterNotifyTopicsArray;
|
||||
this.notifyTo(this.afterNotifyTopicsArray, [data, e, this]);
|
||||
break;
|
||||
case "error":
|
||||
topicsArray = this.errorNotifyTopicsArray;
|
||||
break;
|
||||
case "valuechanged":
|
||||
topicsArray = this.valueNotifyTopicsArray;
|
||||
this.notifyTo(this.errorNotifyTopicsArray, [data, e, this]);
|
||||
break;
|
||||
case "valuechanged":
|
||||
this.notifyTo(this.valueNotifyTopicsArray, [this.getSelectedValue(), this.getSelectedKey(), this.getText(), this]);
|
||||
break;
|
||||
}
|
||||
|
||||
this.notifyTo(topicsArray, data, type, e);
|
||||
},
|
||||
|
||||
notifyTo : function(topicsArray, data, type, e) {
|
||||
notifyTo : function(topicsArray, params) {
|
||||
var self = this;
|
||||
if(topicsArray) {
|
||||
dojo.lang.forEach(topicsArray, function(topic) {
|
||||
try {
|
||||
dojo.event.topic.publish(topic, data, type, e);
|
||||
dojo.event.topic.publishApply(topic, params);
|
||||
} catch(ex){
|
||||
self.log(ex);
|
||||
}
|
||||
@@ -492,27 +492,12 @@ dojo.widget.defineWidget(
|
||||
getSelectedKey : function() {
|
||||
return this.comboBoxSelectionValue.value;
|
||||
},
|
||||
|
||||
setSelectedValue : function(text) {
|
||||
if(this.dataProvider) {
|
||||
var data = this.dataProvider.data;
|
||||
for(element in data) {
|
||||
var obj = data[element];
|
||||
if(obj[0].toString() == text) {
|
||||
this.setValue(obj[0].toString());
|
||||
this.comboBoxSelectionValue.value = obj[1].toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.comboBoxSelectionValue.value = text;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getSelectedValue : function() {
|
||||
return this.comboBoxValue.value;
|
||||
},
|
||||
|
||||
getText : function() {
|
||||
return this.textInputNode.value();
|
||||
return this.textInputNode.value;
|
||||
}
|
||||
});
|
||||
|
||||
File diff suppressed because one or more lines are too long
+20
-35
@@ -24162,12 +24162,13 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
|
||||
//if notifyTopics is published on the first request (onload)
|
||||
//the value of listeners will be reset
|
||||
if(!this.firstRequest) {
|
||||
this.firstRequest = false;
|
||||
if(!this.firstRequest || type == "error") {
|
||||
this.cbox.notify.apply(this.cbox, [data, type, evt]);
|
||||
}
|
||||
|
||||
this.firstRequest = false;
|
||||
var arrData = null;
|
||||
var dataByName = data[this.cbox.dataFieldName];
|
||||
var dataByName = data[dojo.string.isBlank(this.cbox.dataFieldName) ? this.cbox.name : this.cbox.dataFieldName];
|
||||
if(!dojo.lang.isArray(data)) {
|
||||
//if there is a dataFieldName, take it
|
||||
if(dataByName) {
|
||||
@@ -24178,7 +24179,7 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
//it is an object, treat it like a map
|
||||
arrData = [];
|
||||
for(var key in dataByName){
|
||||
arrData.push([dataByName[key], key]);
|
||||
arrData.push([key, dataByName[key]]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -24192,7 +24193,7 @@ struts.widget.ComboBoxDataProvider = function(combobox, node){
|
||||
} else {
|
||||
//if nathing else is found, we will use values in this
|
||||
//object as the data
|
||||
tmpArrData.push([data[key], key]);
|
||||
tmpArrData.push([key, data[key]]);
|
||||
}
|
||||
//grab the first array found, we will use it if nothing else
|
||||
//is found
|
||||
@@ -24541,12 +24542,13 @@ dojo.widget.defineWidget(
|
||||
},
|
||||
|
||||
notify : function(data, type, e) {
|
||||
var self = this;
|
||||
//general topics
|
||||
if(this.notifyTopicsArray) {
|
||||
var self = this;
|
||||
dojo.lang.forEach(this.notifyTopicsArray, function(topic) {
|
||||
try {
|
||||
dojo.event.topic.publish(topic, data, type, e);
|
||||
} catch(ex) {
|
||||
dojo.event.topic.publish(topic, data, type, e, self);
|
||||
} catch(ex){
|
||||
self.log(ex);
|
||||
}
|
||||
});
|
||||
@@ -24556,28 +24558,26 @@ dojo.widget.defineWidget(
|
||||
var topicsArray = null;
|
||||
switch(type) {
|
||||
case "before":
|
||||
topicsArray = this.beforeNotifyTopicsArray;
|
||||
this.notifyTo(this.beforeNotifyTopicsArray, [e, this]);
|
||||
break;
|
||||
case "load":
|
||||
topicsArray = this.afterNotifyTopicsArray;
|
||||
this.notifyTo(this.afterNotifyTopicsArray, [data, e, this]);
|
||||
break;
|
||||
case "error":
|
||||
topicsArray = this.errorNotifyTopicsArray;
|
||||
break;
|
||||
case "valuechanged":
|
||||
topicsArray = this.valueNotifyTopicsArray;
|
||||
this.notifyTo(this.errorNotifyTopicsArray, [data, e, this]);
|
||||
break;
|
||||
case "valuechanged":
|
||||
this.notifyTo(this.valueNotifyTopicsArray, [this.getSelectedValue(), this.getSelectedKey(), this.getText(), this]);
|
||||
break;
|
||||
}
|
||||
|
||||
this.notifyTo(topicsArray, data, type, e);
|
||||
},
|
||||
|
||||
notifyTo : function(topicsArray, data, type, e) {
|
||||
notifyTo : function(topicsArray, params) {
|
||||
var self = this;
|
||||
if(topicsArray) {
|
||||
dojo.lang.forEach(topicsArray, function(topic) {
|
||||
try {
|
||||
dojo.event.topic.publish(topic, data, type, e);
|
||||
dojo.event.topic.publishApply(topic, params);
|
||||
} catch(ex){
|
||||
self.log(ex);
|
||||
}
|
||||
@@ -24620,28 +24620,13 @@ dojo.widget.defineWidget(
|
||||
getSelectedKey : function() {
|
||||
return this.comboBoxSelectionValue.value;
|
||||
},
|
||||
|
||||
setSelectedValue : function(text) {
|
||||
if(this.dataProvider) {
|
||||
var data = this.dataProvider.data;
|
||||
for(element in data) {
|
||||
var obj = data[element];
|
||||
if(obj[0].toString() == text) {
|
||||
this.setValue(obj[0].toString());
|
||||
this.comboBoxSelectionValue.value = obj[1].toString();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.comboBoxSelectionValue.value = text;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
getSelectedValue : function() {
|
||||
return this.comboBoxValue.value;
|
||||
},
|
||||
|
||||
getText : function() {
|
||||
return this.textInputNode.value();
|
||||
return this.textInputNode.value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user