Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > Java > Javascript噩梦-Ajax实现输入提示的调整与配置
【标  题】:Javascript噩梦-Ajax实现输入提示的调整与配置
【关键字】:Javascript,Ajax
【来  源】:http://www.blogjava.net/richardeee/archive/2007/02/01/97380.html

Javascript噩梦-Ajax实现输入提示的调整与配置

Your Ad Here 经过一个星期的煎熬,终于把基于Ajax的输入提示功能实现了。太痛苦了,写Javascript的感觉就跟用NotePad来写代码一样,没有智能提示、弱类型、难调试……总之是太折磨人了。
本来自己写了一个比较简单的,但是由于我的页面上需要多个输入框,还要可以动态增加输入框,要把传回来的结果set入多个输入框,由于是使用的Struts标签库,<html:text>还没有id属性,让这个问题复杂了不少。
需求是这样的:
有一个页面,需要录入货品信息,货品有id,编号,名称,单位,单价,规格等属性,每个货品信息在表格中有一行,一行中有多个输入框,用于输入货品信息。在输入货品编号的时候,应该访问后台的商品信息库,寻找以前是否有输入过该编号的货品,如果有,把编号返回。支持用鼠标点击,键盘回车等方法选择货品,选择后应该把货品信息显示到各个输入框中供用户修改。如果该货品在商品信息库中标记为敏感商品,要作出提示。一个编号可以有多个货品。
改了3天代码,终于决定破釜沉舟,删掉重做。修改了《Ajax in Action》中的代码,Ajax in Action中的代码有些地方有错误,不仔细检查一遍还真不太容易发现。书中后台使用C#,前台是使用Rico来向某个url传参数的形式进行Ajax通信。返回的response类似:
<ajax-response>
??
<response?type='object'?id='field1_updater'>
????
<matches>
??????
<text>XXX</text>
??????
<value>XXX</value>
????
</matches>
??
</response>
</ajax-response>
不过我不想写JSP或者Servlet,所以用了DWR,直接用spring中的BO把结果传回来:
cargobaseService.getByNumberAndCompany(this.lastRequestString,this.company,function(ajaxResponse){
//
}
);
cargobaseService是使用DWR创建的Javascript对象:
dwr.xml:
<dwr>
??
<allow>
????
<create?creator="spring"?javascript?=?"cargobaseService">
????????
<param?name="beanName"?value="cargobaseService"/>
????
</create>
????
<convert?match="com.gdnfha.atcs.cargobase.model.*"?converter="bean"></convert>
??
</allow>
</dwr>
返回为下面对象的数组
var?cargoModel?=?{
??cargoCompany:?XXX,
??cargoCurrency:?XXX,
??cargoDestination:?XXX,
??cargoId:?XXX,
??cargoImpose:?XXX,
??cargoName:?XXX,
??cargoNumber:?XXX,
??cargoSize:?XXX,
??cargoUnit:?XXX,
??cargoUnitPrice:?XXX,
??sensitive:?
true|false
}
?Javascript代码如下:
TextSuggest?=?Class.create();

TextSuggest.prototype?
=?{
????
//构造函数
???initialize:?function(anId,company,?url,?options)?{
??????
this.id??????????=?anId;
??????
this.company?=?company;
??????
var?browser?=?navigator.userAgent.toLowerCase();
??????
this.isIE????????=?browser.indexOf("msie")?!=?-1;
??????
this.isOpera?????=?browser.indexOf("opera")!=?-1;
??????
this.textInput???=?$(this.id);
??????
this.suggestions?=?new?Array();
??????
this.setOptions(options);
??????
this.injectSuggestBehavior();
???}
,
????
//设置参数
???setOptions:?function(options)?{
??????
this.options?=?{
?????????suggestDivClassName:?'suggestDiv',
?????????suggestionClassName:?'suggestion',
?????????matchClassName?????:?'match',
?????????matchTextWidth?????:?
true,
?????????selectionColor?????:?'#b1c09c',
?????????matchAnywhere??????:?
false,
?????????ignoreCase?????????:?
false,
?????????count??????????????:?
10
??????}
.extend(options?||?{});
???}
,
????
//注入输入提示行为
???injectSuggestBehavior:?function()?{

??????
if?(?this.isIE?)
?????????
this.textInput.autocomplete?=?"off";
????
//创建控制器
??????var?keyEventHandler?=?new?TextSuggestKeyHandler(this);
??????
//主要是为了避免在按回车的时候把表单提交
??????new?Insertion.After(?this.textInput,
???????????????????????????'
<input?type="text"?id="'+this.id+'_preventtsubmit'+'"?style="display:none"/>'?);
??????
new?Insertion.After(?this.textInput,
???????????????????????????'
<input?type="hidden"?name="'+this.id+'_hidden'+'"?id="'+this.id+'_hidden'+'"/>'?);
????
//创建div层
??????this.createSuggestionsDiv();
???}
,
????
//处理输入信息
???handleTextInput:?function()?{
?????
var?previousRequest????=?this.lastRequestString;
?????
this.lastRequestString?=?this.textInput.value;
?????
if?(?this.lastRequestString?==?""?)
????????
this.hideSuggestions();
?????
else?if?(?this.lastRequestString?!=?previousRequest?)?{
?????????
//访问数据源
????????this.sendRequestForSuggestions();
?????}

???}
,
????
//选择框上移
???moveSelectionUp:?function()?{
??????
if?(?this.selectedIndex?>?0?)?{
?????????
this.updateSelection(this.selectedIndex?-?1);
??????}

???}
,
????
//选择框下移
???moveSelectionDown:?function()?{
??????
if?(?this.selectedIndex?<?(this.suggestions.length?-?1)??)?{
?????????
this.updateSelection(this.selectedIndex?+?1);
??????}

???}
,
????
//更新当前选择信息
???updateSelection:?function(n)?{
??????
var?span?=?$(?this.id?+?"_"?+?this.selectedIndex?);
??????
if?(?span?){
??????????
//消除以前的样式
?????????span.style.backgroundColor?=?"";
??????}

??????
this.selectedIndex?=?n;
??????
var?span?=?$(?this.id?+?"_"?+?this.selectedIndex?);
??????
if?(?span?){
??????????
//更新新样式
?????????span.style.backgroundColor?=?this.options.selectionColor;
??????}

???}
,
????
//发送请求
???sendRequestForSuggestions:?function()?{
?????
if?(?this.handlingRequest?)?{
????????
this.pendingRequest?=?true;
????????
return;
?????}


?????
this.handlingRequest?=?true;
?????
this.callDWRAjaxEngine();
???}
,

????
//使用DWR访问后台
???callDWRAjaxEngine:?function()?{
???????????
//保存当前对象指针
???????????var?tempThis?=?this;
???????????cargobaseService.getByNumberAndCompany(
this.lastRequestString,this.company,function(ajaxResponse){
????????????tempThis.suggestions?
=?ajaxResponse;
??????????????
if?(?tempThis.suggestions.length?==?0?)?{
?????????????????tempThis.hideSuggestions();
?????????????????$(?tempThis.id?
+?"_hidden"?).value?=?"";
??????????????}
else?{
?????????????????tempThis.updateSuggestionsDiv();
?????????????????tempThis.showSuggestions();
?????????????????tempThis.updateSelection(
0);
??????????????}

??????????????tempThis.handlingRequest?
=?false;
????????????
if?(?tempThis.pendingRequest?)?{
????????????????tempThis.pendingRequest????
=?false;
?????????????????tempThis.lastRequestString?
=?this.textInput.value;
?????????????????tempThis.sendRequestForSuggestions();
??????????????}

???????????}
);
???}
,
???
//显示信息
???setInputFromSelection:?function()?{
???????
var?index?=?this.id.split("_");
???????
var?trId?=?"cargoTr_"?+?index[1];
???????
var?trElement?=?$(trId);
???????
var?cellNodes?=?trElement.childNodes;
?????
var?suggestion??=?this.suggestions[?this.selectedIndex?];
????
for(var?i?=?0;?i?<?cellNodes.length;?i++){
????????
var?cargo?=?cellNodes[i].firstChild;
????????
if(cargo.name?==?"cargoName"){
????????????cargo.value?
=?suggestion.cargoName;
????????}

????????
if(cargo.name?==?"cargoSize"){
????????????cargo.value?
=?suggestion.cargoSize;
????????}

????????
if(cargo.name?==?"cargoUnit"){
????????????cargo.value?
==?suggestion.cargoUnit;
????????}

????????
if(cargo.name?==?"cargoDestination"){
????????????cargo.value?
=?suggestion.cargoDestination;
????????}

????????
if(cargo.name?==?"cargoUnitPrice"){
????????????cargo.value?
=?suggestion.cargoUnitPrice;
????????}

????}

?????
this.textInput.value?=?suggestion.cargoNumber;
?????
//敏感提示
?????if(suggestion.sensitive){
?????????
var?warnStr?=?"注意!\n编号:"+suggestion.cargoNumber
?????????????????????????????????
+"\n名称:"?+?suggestion.cargoName
?????????????????????????????????
+"\n为敏感商品!";
?????????alert(warnStr);?
?????}

?????
this.hideSuggestions();
???}
,
????
//显示层
???showSuggestions:?function()?{
??????
var?divStyle?=?this.suggestionsDiv.style;
??????
if?(?divStyle.display?==?''?)
?????????
return;
??????
this.positionSuggestionsDiv();
??????divStyle.display?
=?'';
???}
,
????
//定位层
???positionSuggestionsDiv:?function()?{
??????
var?textPos?=?RicoUtil.toDocumentPosition(this.textInput);
??????
var?divStyle?=?this.suggestionsDiv.style;
??????divStyle.top??
=?(textPos.y?+?this.textInput.offsetHeight)?+?"px";
??????divStyle.left?
=?textPos.x?+?"px";

??????
if?(?this.options.matchTextWidth?)
?????????divStyle.width?
=?(this.textInput.offsetWidth-?this.padding())?+?"px";
???}
,
????
//计算间隔
???padding:?function()?{
?????
try{
??????
var?styleFunc?=?RicoUtil.getElementsComputedStyle;
??????
var?lPad????=?styleFunc(?this.suggestionsDiv,?"paddingLeft",??????"padding-left"?);
??????
var?rPad????=?styleFunc(?this.suggestionsDiv,?"paddingRight",?????"padding-right"?);
??????
var?lBorder?=?styleFunc(?this.suggestionsDiv,?"borderLeftWidth",??"border-left-width"?);
??????
var?rBorder?=?styleFunc(?this.suggestionsDiv,?"borderRightWidth",?"border-right-width"?);

??????lPad????
=?isNaN(lPad)??????0?:?lPad;
??????rPad????
=?isNaN(rPad)??????0?:?rPad;
??????lBorder?
=?isNaN(lBorder)???0?:?lBorder;
??????rBorder?
=?isNaN(rBorder)???0?:?rBorder;

??????
return?parseInt(lPad)?+?parseInt(rPad)?+?parseInt(lBorder)?+?parseInt(rBorder);
?????}
catch?(e){
??????
return?0;
?????}

???}
,
????
//隐藏层
???hideSuggestions:?function()?{
??????
this.suggestionsDiv.style.display?=?'none';
???}
,
????
//创建层
???createSuggestionsDiv:?function()?{
??????
this.suggestionsDiv?=?document.createElement("div");
??????
this.suggestionsDiv.className?=?this.options.suggestDivClassName;

??????
var?divStyle?=?this.suggestionsDiv.style;
??????divStyle.position?
=?'absolute';
??????divStyle.zIndex???
=?101;
??????divStyle.display??
=?"none";

??????
this.textInput.parentNode.appendChild(this.suggestionsDiv);
???}
,
????
//更新层
???updateSuggestionsDiv:?function()?{
??????
this.suggestionsDiv.innerHTML?=?"";
??????
var?suggestLines?=?this.createSuggestionSpans();
??????
for?(?var?i?=?0?;?i?<?suggestLines.length?;?i++?)
?????????
this.suggestionsDiv.appendChild(suggestLines[i]);
???}
,
????
//创建层中的选项span
???createSuggestionSpans:?function()?{
??????
var?regExpFlags?=?"";
??????
if?(?this.options.ignoreCase?)
?????????regExpFlags?
=?'i';
??????
var?startRegExp?=?"^";
??????
if?(?this.options.matchAnywhere?)
?????????startRegExp?
=?'';
?????????
//正则表达式匹配
??????var?regExp??=?new?RegExp(?startRegExp?+?this.lastRequestString,?regExpFlags?);
??????
var?suggestionSpans?=?new?Array();
??????
for?(?var?i?=?0?;?i?<?this.suggestions.length?;?i++?)
?????????suggestionSpans.push(?
this.createSuggestionSpan(?i,?regExp?)?)

??????
return?suggestionSpans;
???}
,
????
//创建单个选项span
???createSuggestionSpan:?function(?n,?regExp?)?{
??????
var?suggestion?=?this.suggestions[n];

??????
var?suggestionSpan?=?document.createElement("span");
??????suggestionSpan.className?
=?this.options.suggestionClassName;
??????suggestionSpan.style.width???
=?'100%';
??????suggestionSpan.style.display?
=?'block';
??????suggestionSpan.id????????????
=?this.id?+?"_"?+?n;
??????suggestionSpan.onmouseover???
=?this.mouseoverHandler.bindAsEventListener(this);
??????suggestionSpan.onclick???????
=?this.itemClickHandler.bindAsEventListener(this);
??????
var?textValues?=?this.splitTextValues(?suggestion.cargoNumber+"",
?????????????????????????????????????????????
this.lastRequestString.length,
?????????????????????????????????????????????regExp?);
??????
var?textMatchSpan?=?document.createElement("span");
??????textMatchSpan.id????????????
=?this.id?+?"_match_"?+?n;
??????textMatchSpan.className?????
=?this.options.matchClassName;
??????textMatchSpan.onmouseover???
=?this.mouseoverHandler.bindAsEventListener(this);
??????textMatchSpan.onclick???????
=?this.itemClickHandler.bindAsEventListener(this);

??????textMatchSpan.appendChild(?document.createTextNode(textValues.mid)?);

??????suggestionSpan.appendChild(?document.createTextNode(?textValues.start?)?);
??????suggestionSpan.appendChild(?textMatchSpan?);
??????suggestionSpan.appendChild(?document.createTextNode(?textValues.end?)?);

??????
return?suggestionSpan;
???}
,
????
//鼠标经过处理