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:
Musachy Barroso
2007-06-06 23:14:00 +00:00
parent c72fb7dcf4
commit 3f2e01dd3a
4 changed files with 1239 additions and 1221 deletions
@@ -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");
* }
* &lt;/script&gt;
* </pre>
* <!-- START SNIPPET: example5 -->
*
* <!-- START SNIPPET: example6 -->
* <p>Using beforeNotifyTopics:</p>
* <pre>
* &lt;script type="text/javascript"&gt;
* 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
* });
* &lt;/script&gt;
*
* &lt;sx:autocompleter beforeNotifyTopics="/before" href="%{#ajaxTest} /&gt;
* </pre>
* <!-- END SNIPPET: example6 -->
*
* <!-- START SNIPPET: example7 -->
* <p>Using afterNotifyTopics:</p>
* <pre>
* &lt;script type="text/javascript"&gt;
* 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
* });
* &lt;/script&gt;
*
* &lt;sx:autocompleter afterNotifyTopics="/after" href="%{#ajaxTest}" /&gt;
* </pre>
* <!-- END SNIPPET: example7 -->
*
* <!-- START SNIPPET: example8-->
* <p>Using errorNotifyTopics:</p>
* <pre>
* &lt;script type="text/javascript"&gt;
* 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
* });
* &lt;/script&gt;
*
* &lt;sx:autocompleter errorNotifyTopics="/error" href="%{#ajaxTest}" /&gt;
* </pre>
* <!-- END SNIPPET: example8 -->
*
* <!-- START SNIPPET: example9 -->
* <p>Using valueNotifyTopics and indicator:</p>
* <pre>
* &lt;script type="text/javascript"&gt;
* 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
* });
* &lt;/script&gt;
* <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 {
@@ -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
@@ -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;
}
});