Posted on 2006-01-17 23:11
JavaXP 阅读(4642)
评论(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)");
}
再改一下`他调用的地方,换成这个方法就好了`噎!