* Update autocompleter to accept JSON generated using the JSON plugin
 * Add "dataFieldName" to identify the field to be used as the data source in the returned JSON string


git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@510743 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Musachy Barroso
2007-02-23 01:06:19 +00:00
parent 2a60666d63
commit 79ee4c3845
7 changed files with 60 additions and 16 deletions
@@ -31,15 +31,7 @@ import com.opensymphony.xwork2.util.ValueStack;
/**
* <p>The autocomplete tag is a combobox that can autocomplete text entered on the input box.
* When used on the "simple" theme, the autocompleter can be used like the ComboBox.
* When used on the "ajax" theme, the list can be retieved from an action. This action must
* return a JSON list in the format:</p>
* <pre>
* [
* ["Text 1","Value1"],
* ["Text 2","Value2"],
* ["Text 3","Value3"]
* ]
* </pre>
* When used on the "ajax" theme, the list can be retieved from an action. </p>
* <!-- START SNIPPET: ajaxJavadoc -->
* <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
* <ul>
@@ -75,6 +67,7 @@ import com.opensymphony.xwork2.util.ValueStack;
* 'keyName' name of the field to which the selected key will be assigned<p/>
* 'iconPath' path of icon used for the dropdown
* 'templateCssPath' path to css file used to customize Dojo's widget
* 'dataFieldName' name of the field to be used as the list in the returned JSON string<p/>
* 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
* <ul>
* <li>data: selected value when type='valuechanged'</li>
@@ -107,6 +100,7 @@ public class Autocompleter extends ComboBox {
protected String templateCssPath;
protected String iconPath;
protected String keyName;
protected String dataFieldName;
public Autocompleter(ValueStack stack, HttpServletRequest request,
HttpServletResponse response) {
@@ -169,6 +163,8 @@ public class Autocompleter extends ComboBox {
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 {
@@ -285,4 +281,9 @@ public class Autocompleter extends ComboBox {
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;
}
}
@@ -53,6 +53,7 @@ public class AutocompleterTag extends ComboBoxTag {
protected String templateCssPath;
protected String iconPath;
protected String keyName;
protected String dataFieldName;
public Component getBean(ValueStack stack, HttpServletRequest req, HttpServletResponse res) {
return new Autocompleter(stack, req, res);
@@ -81,6 +82,7 @@ public class AutocompleterTag extends ComboBoxTag {
autocompleter.setTemplateCssPath(templateCssPath);
autocompleter.setIconPath(iconPath);
autocompleter.setKeyName(keyName);
autocompleter.setDataFieldName(dataFieldName);
}
public void setAutoComplete(String autoComplete) {
@@ -162,4 +164,8 @@ public class AutocompleterTag extends ComboBoxTag {
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public void setDataFieldName(String dataFieldName) {
this.dataFieldName = dataFieldName;
}
}
@@ -63,12 +63,28 @@ struts.widget.ComboBoxDataProvider = function(/*Array*/ dataPairs, /*Number*/ li
dojo.html.hide(this.cbox.indicator);
this.cbox.notify.apply(this.cbox, [data, type, evt]);
if(!dojo.lang.isArray(data)){
var arrData = [];
for(var key in data){
arrData.push([data[key], key]);
}
data = arrData;
if(!dojo.lang.isArray(data)) {
//if there is a dataFieldName, take it
if(!dojo.string.isBlank(this.cbox.dataFieldName) && data[this.cbox.dataFieldName] != null) {
arrData = data[this.cbox.dataFieldName];
} else {
//try to find a match
var arrData = null;
for(var key in data){
//does it start with the field name? take it
if(key == this.cbox.name) {
arrData = data[key];
break;
}
//grab the first array found, we will use it if nothing else
//is found
if(!arrData && dojo.lang.isArray(data[key])) {
arrData = data = data[key];
}
}
}
data = arrData;
}
this.setData(data);
}),
@@ -167,6 +183,13 @@ struts.widget.ComboBoxDataProvider = function(/*Array*/ dataPairs, /*Number*/ li
this.setData = function(/*Array*/ pdata){
// populate this.data and initialize lookup structures
this.data = pdata;
//all ellements must be a key and value pair
for(var i = 0; i < this.data.length; i++) {
var element = this.data[i];
if(!dojo.lang.isArray(element)) {
this.data[i] = [element, element];
}
}
};
if(dataPairs){
@@ -205,6 +228,7 @@ dojo.widget.defineWidget(
//dojo has "stringstart" which is invalid
searchType: "STARTSTRING",
dataFieldName : "" ,
keyName: "",
templateCssPath: dojo.uri.dojoUri("struts/ComboBox.css"),
//from Dojo's ComboBox
@@ -86,6 +86,9 @@
<#if parameters.templateCssPath?if_exists != "">
templateCssPath="<@s.url value='${parameters.templateCssPath}' encode="false" includeParams='none'/>"
</#if>
<#if parameters.dataFieldName?if_exists != "">
dataFieldName="${parameters.dataFieldName?html}"
</#if>
<#include "/${parameters.templateDir}/simple/scripting-events.ftl" />
>
@@ -59,6 +59,14 @@ Please do not edit it directly.
<td align="left" valign="top">String</td>
<td align="left" valign="top">The css style definitions for element ro use</td>
</tr>
<tr>
<td align="left" valign="top">dataFieldName</td>
<td align="left" valign="top">false</td>
<td align="left" valign="top">Value specified in 'name'</td>
<td align="left" valign="top">true</td>
<td align="left" valign="top">String</td>
<td align="left" valign="top">Name of the field in the returned JSON object that contains the data array</td>
</tr>
<tr>
<td align="left" valign="top">delay</td>
<td align="left" valign="top">false</td>
@@ -49,6 +49,7 @@ public class AutocompleterTest extends AbstractUITagTest {
tag.setShowDownArrow("false");
tag.setIconPath("i");
tag.setTemplateCssPath("j");
tag.setDataFieldName("k");
tag.doStartTag();
tag.doEndTag();
@@ -16,4 +16,5 @@
loadMinimum="3"
visibleDownArrow="false"
buttonSrc="i"
templateCssPath="j">
templateCssPath="j"
dataFieldName="k">