Posted on 2006-01-17 23:11
JavaXP 閱讀(4667)
評論(17) 編輯 收藏 所屬分類:
實戰經驗
昨天下午突然接到公司通知,以前處理的XX物資系統的部門,班組,工程,供應廠商部分都需要修改成Ajaxtags的autocomplete來完成,用戶需要輸入查詢碼來進行索引,于是開始動手研究Ajaxtags.
Ajaxtags是基于prototype.js的簡化AJAX開發的組件,可以通過標簽來來完成以前非常復雜的事情.
通過DOME和原代碼的分析,我感覺,他的簡化過于局限,沒有非常好擴展性,只能做一些簡單的處理,比方他的AjaxXmlBuilder的toString()方法可以返回一種簡單的XML格式,而且過于簡單:
<?xml version="1.0" encoding="UTF-8"?>
<ajax-response>
<response>
<item>
<name>Record 1</name>
<value>1</value>
</item>
<item>
<name>Record 2</name>
<value>2</value>
</item>
<item>
<name>Record 3</name>
<value>3</value>
</item>
</response>
</ajax-response>

他在autocomplete處理時會用到這中XML文件:
以下是在他的JS中解析XML的部分
var name = items[i].getElementsByTagName("name")[0].firstChild.nodeValue;
var value = items[i].getElementsByTagName("value")[0].firstChild.nodeValue;由此可以看出他過于簡單,如果我有多個屬性需要放入自動下拉菜單中怎么辦?
好辦,我們擴展!
自己造一個AjaxXmlBuilder,繼承一下就可以了,把toString()方法重載掉~讓他組一個我要的XML文件出來,然后再到頁面上自己解吸他`就OK了~
我的類:
package com.kaiwang.mmis.ajax.autoselect;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import org.ajaxtags.helpers.AjaxXmlBuilder;
import org.apache.commons.beanutils.BeanUtils;


/** *//**
* 重載ajaxxmlbuilder封裝出新的xml文件
* @author Gary.lee Jan 16, 2006
*/

public class ManufacturerXmlBuilder extends AjaxXmlBuilder implements MisAjaxXmlBuilder
{
private String encoding = "UTF-8";
private List items = new ArrayList();

public ManufacturerXmlBuilder addItems(Collection collection, String nameProperty, String valueProperty, String seachCodeProperty) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException
{

for (Iterator iter = collection.iterator(); iter.hasNext();)
{
Object element = (Object) iter.next();
String name = BeanUtils.getProperty(element, nameProperty);
String value = BeanUtils.getProperty(element, valueProperty);
String seachCode = BeanUtils.getProperty(element, seachCodeProperty);
items.add(new MisAjaxBaseItem(name, value, seachCode));
}
return this;
}


/** *//**
* @see java.lang.Object#toString()
*/

public String toString()
{
StringBuffer xml = new StringBuffer().append("<?xml version=\"1.0\"");

if (encoding != null)
{
xml.append(" encoding=\"");
xml.append(encoding);
xml.append("\"");
}
xml.append(" ?>");

xml.append("<ajax-response>");
xml.append("<response>");

for (Iterator iter = items.iterator(); iter.hasNext();)
{
MisAjaxBaseItem item = (MisAjaxBaseItem) iter.next();
xml.append("<item>");
xml.append("<name>");
xml.append("<![CDATA[");
xml.append(item.getName());
xml.append("]]>");
xml.append("</name>");
xml.append("<value>");
xml.append("<![CDATA[");
xml.append(item.getId());
xml.append("]]>");
xml.append("</value>");
xml.append("<searchcode>");
xml.append("<![CDATA[");
xml.append(item.getSearchCode());
xml.append("]]>");
xml.append("</searchcode>");
xml.append("</item>");
}
xml.append("</response>");
xml.append("</ajax-response>");
return xml.toString();
}
}

這樣就有了我要的XML文件格式了~再修改JS
var name = items[i].getElementsByTagName("name")[0].firstChild.nodeValue;
var value = items[i].getElementsByTagName("value")[0].firstChild.nodeValue;
//新增加一個searchcode部分的解析
var searchCode = items[i].getElementsByTagName("searchcode")[0].firstChild.nodeValue;
var li = document.createElement("li");
var liIdAttr = document.createAttribute("id");
li.setAttribute("id", value);
//將searchcode部分+name輸出到文本區域中
var liText = document.createTextNode(name+'('+searchCode+')');大家可以看到,我加入了一個
searchCode的東西就是在下拉框中把searchCode打印出來!
效果~~~~~~我抓張圖出來看看:

樣子還可以吧`!
用過autocomplete的朋友應該知道如果僅僅是鼠標點擊以后這個框是不會出來了~
因為他默認的事件是"keyup",也就是當有輸入的時候才出來.初始化的部分在JS中:

setOptions: function(options)
{

this.options =
{
sourceElem: $(options.source),
targetElem: $(options.target),
eventType: options.eventType ? options.eventType : "keyup",
appendValue: evalBoolean(options.appendValue),
appendSeparator: options.appendSeparator || " ",
forceSelection: evalBoolean(options.forceSelection)

}.extend(options ||
{});而且這里如果換成"force"的話,在下拉框中的上下鍵和回車就失效了,沒關系!解決了!在調用的時候把
eventType:"focus" 加上(這個屬性官方文檔中并沒有說~)然后找到:

attachBehaviors: function(element, event, listener, obj)
{

if (isArray(element))
{

for (var i=0; i<element.length; i++)
{
eval("element[i].on"+event+" = listener.bindAsEventListener(obj)");
}

} else
{
eval("element.on"+event+" = listener.bindAsEventListener(obj)");
eval("element.onkeyup = listener.bindAsEventListener(obj)");
}
}大家可以看到我在下面又追加了一個“keyup”的屬性,這樣既在得到焦點的時候可以出來,也可以在用上下建的時候選擇,還可以做篩選~還有就是我沒有實用標簽,我讀了它的DOME以后發現它僅僅是封裝了JS而已,用了標簽以后感覺怪怪的,為什么JS的調用也要用標簽封裝呢?僅僅是可以在標簽中實用EL語法·但是又有多少兄弟會用呢?最主要的是它的標簽中好想沒有“eventType”這個屬性~,看看我的調用:
//班站編號

new AjaxJspTag.Autocomplete("<%=request.getContextPath()%>/autoSelectTeam.do",
{
parameters:"team={team_Name},depId={department_Id}",
progressStyle:"throbbing",
target:"team_Id",
className:"autocomplete",
source:"team_Name",
forceSelection:"yes",
eventType:"focus"
});
要注意的是parameters這里多參數實用了,號隔開,這樣到ACTION中就可以用depId接到值了~這個東西在官方文檔中也沒有說出來,還是同事發現的~
!
本人文采不行``大家見諒,希望文章對用ajaxTags的朋友有寫幫助,我的原則就是·能改的我都改·只要我能用就可以了!
我再改~前面說了,我修改了AJAX基本的JS文件``但是他的其他屬性就不能用了~~~很痛苦,所以晚上突然想到,我專門為他加一個方法就可以了~
//事件觸發(修改增加一個keyup事件auto專用)

attachBehaviorsAuto: function(element, event, listener, obj)
{
eval("element.on"+event+" = listener.bindAsEventListener(obj)");
eval("element.onkeyup = listener.bindAsEventListener(obj)");
}
再改一下`他調用的地方,換成這個方法就好了`噎!