create table `suggest` (
`id` int(10) unsigned not null auto_increment,
`keyword` varchar(50) not null,
`num` int(10) unsigned not null,
primary key (`id`)
) engine=myisam default charset=gb2312 auto_increment=59 ;
/*
****************************
*** http://www.hansir.cn ***
****************************
*/
string.prototype.ltrim = function(){
return this.replace(/^s*(.+?)$/,'$1');
}
//这里引用prototype的五个方法
function $(){return document.getelementbyid(arguments[0]);}
object.extend = function(destination, source){
for(property in source) destination[property] = source[property];
return destination;
}
function $a(iterable) {
var results = [];
for (var i = 0; i return results;
}
function.prototype.bindaseventlistener = function(object) {
var __method = this;
return function(event) {
return __method.call(object, event || window.event);
}
}
function.prototype.bind = function() {
var __method = this, args = $a(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($a(arguments)));
}
}
var hansir = {
url: 'http://www.hansir.cn'
}
hansir.ajax = function(){this.initialize.apply(this, arguments);}
hansir.ajax.prototype = {
initialize: function(complete, method, url){
this.complete = complete;
this.method = method || 'post';
this.url = url;
if (this.method == 'get') this.url += (this.url.match(/?/) ? '&' : '?');
},
xmlhttp: function(){
var xmlhttp;
if(window.xmlhttprequest) xmlhttp = new xmlhttprequest();
else if(window.activexobject)
try{
xmlhttp = new activexobject('msxml2.xmlhttp');
}catch(errr){
xmlhttp = new activexobject('microsoft.xmlhttp');
}
return xmlhttp;
},
request: function(parameters){
var xmlhttp = this.xmlhttp();
var send_val = null;
this.method=='get' ? this.url += parameters : send_val = parameters;
xmlhttp.open(this.method, this.url, true);
xmlhttp.setrequestheader('content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xmlhttp.onreadystatechange = this.ready_handler.bind(this, xmlhttp);
xmlhttp.send(send_val);
},
ready_handler: function(xmlhttp){
if(xmlhttp.readystate == 4){
if(this.success(xmlhttp)){
this.complete.load_data(xmlhttp);
}
}
},
success: function(xmlhttp){return xmlhttp.status == 0 || xmlhttp.status >= 200 && xmlhttp.status }
hansir.textsuggest = function(){this.initialize.apply(this, arguments);}
hansir.textsuggest.prototype = {
initialize: function(){},
add_suggest: function(inp, url, method, defer, defer2){
var inp = $(inp);
inp.defer = defer || null;
inp.defer2 = defer2 || 200;
var sw = inp.offsetwidth, sh = inp.offsetheight;
inp.suggest_list = this.create_list(sw, sh);
inp.suggest_list.par = inp;
inp.xmlhttp = new hansir.ajax(inp.suggest_list, method, url);
object.extend(inp, {
requesting : false,
last_result : true,
previous_value : null,
last_value : null,
kt : null,
rt : null,
load_event: function(){
if(this.addeventlistener){
this.addeventlistener('input', this.keyup_handler.bindaseventlistener(this),false);
}else if(this.attachevent){
this.attachevent('onkeyup', this.keyup_handler.bindaseventlistener(this));
}
},
keyup_handler:function(e){
var intkey;
window.event ? intkey = event.keycode : intkey = e.which;
if(intkey == 38 || intkey == 40 || intkey == 13 || intkey == 37) return;
if(this.requesting) return;
var val = this.value.ltrim();
this.last_value = val;
if(val == this.previous_value) return;
if(val==''){
this.previous_value = '';
this.last_value='';
this.suggest_list.hidden();
this.suggest_list.clear_data();
return;
}
if(new regexp('^'+this.last_result,'i').test(val)) return;
this.last_result = true;
this.previous_value = val;
if(this.kt) cleartimeout(this.kt);
this.defer?this.kt = settimeout(this.send_request.bind(this), this.defer):this.send_request();
},
onblur: function(){
settimeout(this.suggest_list.hidden.bind(this.suggest_list), 100);
},
onkeydown: function(e){ // 上下、回车键事件
if(!this.suggest_list.rows.length) return;
var intkey;
window.event ? intkey = event.keycode : intkey = e.which;
switch(intkey){
case 38:
if(this.suggest_list.style.visibility=='hidden'){
this.suggest_list.visible();
return;
}
var val = this.suggest_list.select_index(1);
val?this.value=val : this.value = this.last_value;
break;
case 40:
if(this.suggest_list.style.visibility=='hidden'){
this.suggest_list.visible();
return;
}
var val=this.suggest_list.select_index(0);
val?this.value=val : this.value = this.last_value;
break;
case 13:
if(this.suggest_list.cur_tr!=-1){
this.suggest_list.hidden();
break;
}
case 39:
this.suggest_list.hidden();
this.keyup_handler('o');
}
},
send_request: function(){ // 请求数据
this.requesting = true;
var val = this.value;
var parameters = 'keyword=' + val.ltrim();
this.xmlhttp.request(parameters);
this.start_hidden_time();
},
start_hidden_time: function(){
if(this.rt) cleartimeout(this.rt);
this.rt = settimeout(this.list_hidden.bind(this), this.defer2);
},
list_hidden: function(){
if(this.requesting) this.suggest_list.hidden();
}
});
inp.load_event();
},
create_list: function(w, h){ //创建列表
var table = document.createelement('table');
table.cellspacing = 0;
document.body.appendchild(table);
table.classname = 'tab_suggest';
table.style.width = w + 'px';
table.parh = h-1;
object.extend(table,{
cur_tr: -1,
set_pos: function(){ // 下垃框位置
var x=0, y=0, inp = this.par;
while(inp != null){x += inp.offsetleft;y += inp.offsettop;inp = inp.offsetparent;}
inp = null;
table.style.left = x + 'px';
table.style.top = y+this.parh+ 'px';
},
add: function(str, num){
var n=0;
this.rows.length ? n=this.rows.length : n = 0;
var tr = this.insertrow(n);
var th = document.createelement('th');
var td = document.createelement('td');
th.innerhtml = str, td.innerhtml = num;
tr.appendchild(th), tr.appendchild(td);
tr.num = this.rows.length-1;
tr.par = this;
tr.onmouseover = function(){
var par = this.par;
if(par.cur_tr!=-1 && par.cur_tr!=this.num){
par.rows[par.cur_tr].classname='';
this.classname = 'cur';
par.cur_tr = this.num;
}else{
this.classname = 'cur';
par.cur_tr = this.num;
}
}
tr.onclick = function(){
var par = this.par.par;
par.value = this.cells[0].innerhtml;
}
tr = null, th = null, td = null;
},
load_data: function(xmlhttp){ // 加载列表
var inp = this.par;
if(inp.previous_value != inp.value){
inp.requesting = false;
this.clear_data();
inp.keyup_handler('o');
return;
}
var arr = xmlhttp.responsetext;
if(arr.ltrim() == 'null'){
inp.last_result = inp.value;
inp.requesting = false;
inp.suggest_list.hidden();
this.clear_data();
return;
}
var cur_data = eval(arr);
this.clear_data();
for(var i=0; i this.cur_tr = -1;
this.visible();
inp.requesting = false;
},
clear_data: function(){while(this.rows.length)this.deleterow(this.rows[0])}, // 清空列表
select_index: function(n){ // 移动选项
if(n){
if(this.cur_tr==0){
this.rows[0].classname = '';
this.cur_tr = -1;
return false;
}else{
this.cur_tr==-1?this.cur_tr=this.rows.length : this.rows[this.cur_tr].classname = '';
this.cur_tr = this.cur_tr-1;
this.rows[this.cur_tr].classname = 'cur';
return this.rows[this.cur_tr].cells[0].innerhtml;
}
}else{
if(this.cur_tr == (this.rows.length-1)){
this.rows[this.cur_tr].classname= '';
this.cur_tr = -1;
return false;
}else{
if(this.cur_tr!=-1)this.rows[this.cur_tr].classname = '';
this.cur_tr = this.cur_tr+1;
this.rows[this.cur_tr].classname = 'cur';
return this.rows[this.cur_tr].cells[0].innerhtml;
}
}
},
hidden: function(){this.style.visibility = 'hidden';}, // 隐
visible: function(){this.set_pos(); this.style.visibility = 'visible';} // 显
});
return table;
}
}