dear fellow members,
This is my first post in this forum, I hope for your guidances.
I recently uses autocomplete control from Zichun, a powerful autocomplete control used by youtube as well.
the autocomplete consist of two files:
actb.js
common.js
my problem: atm the autocomplete can only recognise more than one words when they are arranged consecutively in the result, example: when user input "apple bee" it only show result of "apple bee cat", "apple bee dog", "apple bee orange" and so on, but NOT "apple orange bee", "bee apple orage", etc
is there any solution for this?
any help will greatly appreciated.
This is my first post in this forum, I hope for your guidances.
I recently uses autocomplete control from Zichun, a powerful autocomplete control used by youtube as well.
the autocomplete consist of two files:
actb.js
Code:
//////actb.js
function actbpro(obj, ca, hid, ids) {
/* ---- Public Variables ---- */
this.actb_timeOut = -1;
// Autocomplete Timeout in ms (-1: autocomplete never time out)
this.actb_lim =10;
// Number of elements autocomplete can show (-1: no limit)
this.actb_firstText = true;
// should the auto complete be limited to the beginning of keyword?
this.actb_mouse = true;
// Enable Mouse Support
this.actb_delimiter = new Array(';', ',');
// Delimiter for multiple autocomplete. Set it to empty array for single autocomplete
this.actb_startcheck =0;
// Show widget only after this number of characters is typed in.
/* ---- Public Variables ---- */
/* --- Styles --- */
this.actb_bgColor = '#6699CC';
this.actb_textColor = '#000';
this.actb_hColor = '#ffffdb';
this.actb_fFamily = 'Verdana, Geneva, Arial, Helvetica, sans-serif';
this.actb_fSize = '11px';
this.actb_hStyle = 'text-decoration:underline;font-weight="bold"';
/* --- Styles --- */
/* ---- Private Variables ---- */
var actb_delimwords = new Array();
var actb_cdelimword = 0;
var actb_delimchar = new Array();
var actb_display = false;
var actb_pos = 0;
var actb_total = 0;
var actb_curr = null;
var actb_hidd = null;
var actb_rangeu = 0;
var actb_ranged = 0;
var actb_bool = new Array();
var actb_pre = 0;
var actb_toid;
var actb_tomake = false;
var actb_getpre = "";
var actb_mouse_on_list = 1;
var actb_kwcount = 0;
var actb_caretmove = false;
this.actb_keywords = new Array();
this.actb_ids = new Array();
/* ---- Private Variables---- */
this.actb_keywords = ca;
this.actb_ids = ids;
var actb_self = this;
actb_curr = obj;
actb_hidd = hid;
addEvent(actb_curr, "focus", actb_setup);
function actb_setup() {
addEvent(document, "keydown", actb_checkkey);
addEvent(actb_curr, "blur", actb_clear);
addEvent(document, "keypress", actb_keypress);
}
function actb_clear(evt) {
if (!evt) evt = event;
removeEvent(document, "keydown", actb_checkkey);
removeEvent(actb_curr, "blur", actb_clear);
removeEvent(document, "keypress", actb_keypress);
actb_removedisp();
}
function actb_parse(n) {
if (actb_self.actb_delimiter.length > 0) {
var t = actb_delimwords[actb_cdelimword].trim().addslashes();
var plen = actb_delimwords[actb_cdelimword].trim().length;
} else {
var t = actb_curr.value.addslashes();
var plen = actb_curr.value.length;
}
var tobuild = '';
var i;
if (actb_self.actb_firstText) {
var re = new RegExp("^" + t, "i");
} else {
var re = new RegExp(t, "i");
}
var p = n.search(re);
for (i = 0; i < p; i++) {
tobuild += n.substr(i, 1);
}
tobuild += "<font style='" + (actb_self.actb_hStyle) + "'>"
for (i = p; i < plen + p; i++) {
tobuild += n.substr(i, 1);
}
tobuild += "</font>";
for (i = plen + p; i < n.length; i++) {
tobuild += n.substr(i, 1);
}
return tobuild;
}
function actb_generate() {
if (document.getElementById('tat_table')) {
actb_display = false;
document.body.removeChild(document.getElementById('tat_table'));
}
if (actb_kwcount == 0) {
actb_display = false;
return;
}
a = document.createElement('table');
a.cellSpacing = '1px';
a.cellPadding = '2px';
a.style.position = 'absolute';
a.style.top = eval(curTop(actb_curr) + actb_curr.offsetHeight) + "px";
a.style.left = curLeft(actb_curr) + "px";
a.style.backgroundColor = actb_self.actb_bgColor;
a.id = 'tat_table';
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
if (actb_self.actb_mouse) {
a.onmouseout = actb_table_unfocus;
a.onmouseover = actb_table_focus;
}
var counter = 0;
for (i = 0; i < actb_self.actb_keywords.length; i++) {
if (actb_bool[i]) {
counter++;
r = a.insertRow(-1);
if (first && !actb_tomake) {
r.style.backgroundColor = actb_self.actb_hColor;
first = false;
actb_pos = counter;
} else if (actb_pre == i) {
r.style.backgroundColor = actb_self.actb_hColor;
first = false;
actb_pos = counter;
} else {
r.style.backgroundColor = actb_self.actb_bgColor;
}
r.id = 'tat_tr' + (j);
c = r.insertCell(-1);
c.style.color = actb_self.actb_textColor;
c.style.fontFamily = actb_self.actb_fFamily;
c.style.fontSize = actb_self.actb_fSize;
c.innerHTML = actb_parse(actb_self.actb_keywords[i]);
c.id = 'tat_td' + (j);
c.setAttribute('pos', j);
if (actb_self.actb_mouse) {
c.style.cursor = 'pointer';
c.onclick = actb_mouseclick;
c.onmouseover = actb_table_highlight;
}
j++;
}
if (j - 1 == actb_self.actb_lim && j < actb_total) {
r = a.insertRow(-1);
r.style.backgroundColor = actb_self.actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_self.actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_self.actb_fSize;
c.align = 'center';
replaceHTML(c, '\\/');
if (actb_self.actb_mouse) {
c.style.cursor = 'pointer';
c.onclick = actb_mouse_down;
}
break;
}
}
actb_rangeu = 1;
actb_ranged = j - 1;
actb_display = true;
if (actb_pos <= 0) actb_pos = 1;
}
function actb_remake() {
document.body.removeChild(document.getElementById('tat_table'));
a = document.createElement('table');
a.cellSpacing = '1px';
a.cellPadding = '2px';
a.style.position = 'absolute';
a.style.top = eval(curTop(actb_curr) + actb_curr.offsetHeight) + "px";
a.style.left = curLeft(actb_curr) + "px";
a.style.backgroundColor = actb_self.actb_bgColor;
a.id = 'tat_table';
if (actb_self.actb_mouse) {
a.onmouseout = actb_table_unfocus;
a.onmouseover = actb_table_focus;
}
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
if (actb_rangeu > 1) {
r = a.insertRow(-1);
r.style.backgroundColor = actb_self.actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_self.actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_self.actb_fSize;
c.align = 'center';
replaceHTML(c, '/\\');
if (actb_self.actb_mouse) {
c.style.cursor = 'pointer';
c.onclick = actb_mouse_up;
}
}
for (i = 0; i < actb_self.actb_keywords.length; i++) {
if (actb_bool[i]) {
if (j >= actb_rangeu && j <= actb_ranged) {
r = a.insertRow(-1);
r.style.backgroundColor = actb_self.actb_bgColor;
r.id = 'tat_tr' + (j);
c = r.insertCell(-1);
c.style.color = actb_self.actb_textColor;
c.style.fontFamily = actb_self.actb_fFamily;
c.style.fontSize = actb_self.actb_fSize;
c.innerHTML = actb_parse(actb_self.actb_keywords[i]);
c.id = 'tat_td' + (j);
c.setAttribute('pos', j);
if (actb_self.actb_mouse) {
c.style.cursor = 'pointer';
c.onclick = actb_mouseclick;
c.onmouseover = actb_table_highlight;
}
j++;
} else {
j++;
}
}
if (j > actb_ranged) break;
}
if (j - 1 < actb_total) {
r = a.insertRow(-1);
r.style.backgroundColor = actb_self.actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_self.actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_self.actb_fSize;
c.align = 'center';
replaceHTML(c, '\\/');
if (actb_self.actb_mouse) {
c.style.cursor = 'pointer';
c.onclick = actb_mouse_down;
}
}
}
function actb_goup() {
if (!actb_display) return;
if (actb_pos == 1) return;
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_bgColor;
actb_pos--;
if (actb_pos < actb_rangeu) actb_moveup();
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_hColor;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
function actb_godown() {
if (!actb_display) return;
if (actb_pos == actb_total) return;
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_bgColor;
actb_pos++;
if (actb_pos > actb_ranged) actb_movedown();
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_hColor;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
function actb_movedown() {
actb_rangeu++;
actb_ranged++;
actb_remake();
}
function actb_moveup() {
actb_rangeu--;
actb_ranged--;
actb_remake();
}
/* Mouse */
function actb_mouse_down() {
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_bgColor;
actb_pos++;
actb_movedown();
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_hColor;
actb_curr.focus();
actb_mouse_on_list = 0;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
function actb_mouse_up(evt) {
if (!evt) evt = event;
if (evt.stopPropagation) {
evt.stopPropagation();
} else {
evt.cancelBubble = true;
}
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_bgColor;
actb_pos--;
actb_moveup();
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_hColor;
actb_curr.focus();
actb_mouse_on_list = 0;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
function actb_mouseclick(evt) {
if (!evt) evt = event;
if (!actb_display) return;
actb_mouse_on_list = 0;
actb_pos = this.getAttribute('pos');
actb_penter();
}
function actb_table_focus() {
actb_mouse_on_list = 1;
}
function actb_table_unfocus() {
actb_mouse_on_list = 0;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
function actb_table_highlight() {
actb_mouse_on_list = 1;
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_bgColor;
actb_pos = this.getAttribute('pos');
while (actb_pos < actb_rangeu) actb_moveup();
while (actb_pos > actb_ranged) actb_movedown();
document.getElementById('tat_tr' + actb_pos).style.backgroundColor = actb_self.actb_hColor;
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
}
/* ---- */
function actb_insertword(a) {
if (actb_self.actb_delimiter.length > 0) {
str = '';
l = 0;
for (i = 0; i < actb_delimwords.length; i++) {
if (actb_cdelimword == i) {
prespace = postspace = '';
gotbreak = false;
for (j = 0; j < actb_delimwords[i].length; ++j) {
if (actb_delimwords[i].charAt(j) != ' ') {
gotbreak = true;
break;
}
prespace += ' ';
}
for (j = actb_delimwords[i].length - 1; j >= 0; --j) {
if (actb_delimwords[i].charAt(j) != ' ') break;
postspace += ' ';
}
str += prespace;
str += a;
l = str.length;
if (gotbreak) str += postspace;
} else {
str += actb_delimwords[i];
}
if (i != actb_delimwords.length - 1) {
str += actb_delimchar[i];
}
}
actb_curr.value = str;
setCaret(actb_curr, l);
} else {
actb_curr.value = a;
}
actb_mouse_on_list = 0;
actb_removedisp();
}
function actb_inserthidden(index) {
if (actb_hidd)
actb_hidd.value = ids[index];
}
/*
Function executed when an option is selected
*/
function actb_penter() {
if (!actb_display) return;
actb_display = false;
var word = '';
var word_index = 0;
var c = 0;
for (var i = 0; i <= actb_self.actb_keywords.length; i++) {
if (actb_bool[i]) c++;
if (c == actb_pos) {
word = actb_self.actb_keywords[i];
word_index = i
break;
}
}
//alert('here we can handle an hidden with some database id values');
actb_insertword(word);
actb_inserthidden(word_index);
l = getCaretStart(actb_curr);
}
function actb_removedisp() {
if (actb_mouse_on_list == 0) {
actb_display = 0;
if (document.getElementById('tat_table')) {
document.body.removeChild(document.getElementById('tat_table'));
}
if (actb_toid) clearTimeout(actb_toid);
}
}
function actb_keypress(e) {
if (actb_caretmove) stopEvent(e);
return !actb_caretmove;
}
function actb_checkkey(evt) {
if (!evt) evt = event;
a = evt.keyCode;
caret_pos_start = getCaretStart(actb_curr);
actb_caretmove = 0;
switch (a) {
case 38:
actb_goup();
actb_caretmove = 1;
return false;
break;
case 13: case 9:
if (actb_display) {
actb_caretmove = 1;
actb_penter();
return false;
} else {
return true;
}
break;
case 40:
if (actb_curr.value != '') {
actb_godown();
actb_caretmove = 1;
return false;
break;
}
default:
setTimeout(function() {
actb_tocomplete(a)
}, 50);
break;
}
}
function actb_tocomplete(kc) {
if (kc == 38 || (kc == 40 && actb_curr.value != '') || kc == 13) return;
var i;
if (actb_display) {
var word = 0;
var c = 0;
for (var i = 0; i <= actb_self.actb_keywords.length; i++) {
if (actb_bool[i]) c++;
if (c == actb_pos) {
word = i;
break;
}
}
actb_pre = word;
} else {
actb_pre = -1;
}
if (actb_curr.value == '' && kc != 40) {
actb_mouse_on_list = 0;
actb_removedisp();
return;
}
if (actb_self.actb_delimiter.length > 0) {
caret_pos_start = getCaretStart(actb_curr);
caret_pos_end = getCaretEnd(actb_curr);
delim_split = '';
for (i = 0; i < actb_self.actb_delimiter.length; i++) {
delim_split += actb_self.actb_delimiter[i];
}
delim_split = delim_split.addslashes();
delim_split_rx = new RegExp("([" + delim_split + "])");
c = 0;
actb_delimwords = new Array();
actb_delimwords[0] = '';
for (i = 0,j = actb_curr.value.length; i < actb_curr.value.length; i++,j--) {
if (actb_curr.value.substr(i, j).search(delim_split_rx) == 0) {
ma = actb_curr.value.substr(i, j).match(delim_split_rx);
actb_delimchar[c] = ma[1];
c++;
actb_delimwords[c] = '';
} else {
actb_delimwords[c] += actb_curr.value.charAt(i);
}
}
var l = 0;
actb_cdelimword = -1;
for (i = 0; i < actb_delimwords.length; i++) {
if (caret_pos_end >= l && caret_pos_end <= l + actb_delimwords[i].length) {
actb_cdelimword = i;
}
l += actb_delimwords[i].length + 1;
}
var ot = actb_delimwords[actb_cdelimword].trim();
var t = actb_delimwords[actb_cdelimword].addslashes().trim();
} else {
var ot = actb_curr.value;
var t = actb_curr.value.addslashes();
}
//patch to permit swohing the entire list
if (kc == 40 && actb_curr.value == '') {
actb_total = 0;
actb_tomake = false;
actb_kwcount = 0;
for (i = 0; i < actb_self.actb_keywords.length; i++) {
actb_bool[i] = false;
if (actb_self.actb_keywords[i] != '' && actb_self.actb_keywords[i]) {
if (actb_curr.value == '') {
actb_curr.value = actb_self.actb_keywords[i];
}
actb_total++;
actb_bool[i] = true;
actb_kwcount++;
if (actb_pre == i) actb_tomake = true;
}
}
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
return actb_generate();
}
if (ot.length == 0) {
actb_mouse_on_list = 0;
actb_removedisp();
}
if (ot.length < actb_self.actb_startcheck) return this;
if (actb_self.actb_firstText) {
var re = new RegExp("^" + t, "i");
} else {
var re = new RegExp(t, "i");
}
actb_total = 0;
actb_tomake = false;
actb_kwcount = 0;
for (i = 0; i < actb_self.actb_keywords.length; i++) {
actb_bool[i] = false;
if (re.test(actb_self.actb_keywords[i])) {
actb_total++;
actb_bool[i] = true;
actb_kwcount++;
if (actb_pre == i) actb_tomake = true;
}
}
if (actb_toid) clearTimeout(actb_toid);
if (actb_self.actb_timeOut > 0) actb_toid = setTimeout(function() {
actb_mouse_on_list = 0;
actb_removedisp();
}, actb_self.actb_timeOut);
// alert(actb_kwcount)
actb_generate();
}
return this;
}
Code:
/* Event Functions */
// Add an event to the obj given
// event_name refers to the event trigger, without the "on", like click or mouseover
// func_name refers to the function callback when event is triggered
function addEvent(obj,event_name,func_name){
if (obj.attachEvent){
obj.attachEvent("on"+event_name, func_name);
}else if(obj.addEventListener){
obj.addEventListener(event_name,func_name,true);
}else{
obj["on"+event_name] = func_name;
}
}
// Removes an event from the object
function removeEvent(obj,event_name,func_name){
if (obj.detachEvent){
obj.detachEvent("on"+event_name,func_name);
}else if(obj.removeEventListener){
obj.removeEventListener(event_name,func_name,true);
}else{
obj["on"+event_name] = null;
}
}
// Stop an event from bubbling up the event DOM
function stopEvent(evt){
evt || window.event;
if (evt.stopPropagation){
evt.stopPropagation();
evt.preventDefault();
}else if(typeof evt.cancelBubble != "undefined"){
evt.cancelBubble = true;
evt.returnValue = false;
}
return false;
}
// Get the obj that starts the event
function getElement(evt){
if (window.event){
return window.event.srcElement;
}else{
return evt.currentTarget;
}
}
// Get the obj that triggers off the event
function getTargetElement(evt){
if (window.event){
return window.event.srcElement;
}else{
return evt.target;
}
}
// For IE only, stops the obj from being selected
function stopSelect(obj){
if (typeof obj.onselectstart != 'undefined'){
addEvent(obj,"selectstart",function(){ return false;});
}
}
/* Caret Functions */
// Get the end position of the caret in the object. Note that the obj needs to be in focus first
function getCaretEnd(obj){
if(typeof obj.selectionEnd != "undefined"){
return obj.selectionEnd;
}else if(document.selection&&document.selection.createRange){
var M=document.selection.createRange();
try{
var Lp = M.duplicate();
Lp.moveToElementText(obj);
}catch(e){
var Lp=obj.createTextRange();
}
Lp.setEndPoint("EndToEnd",M);
var rb=Lp.text.length;
if(rb>obj.value.length){
return -1;
}
return rb;
}
}
// Get the start position of the caret in the object
function getCaretStart(obj){
if(typeof obj.selectionStart != "undefined"){
return obj.selectionStart;
}else if(document.selection&&document.selection.createRange){
var M=document.selection.createRange();
try{
var Lp = M.duplicate();
Lp.moveToElementText(obj);
}catch(e){
var Lp=obj.createTextRange();
}
Lp.setEndPoint("EndToStart",M);
var rb=Lp.text.length;
if(rb>obj.value.length){
return -1;
}
return rb;
}
}
// sets the caret position to l in the object
function setCaret(obj,l){
obj.focus();
if (obj.setSelectionRange){
obj.setSelectionRange(l,l);
}else if(obj.createTextRange){
m = obj.createTextRange();
m.moveStart('character',l);
m.collapse();
m.select();
}
}
// sets the caret selection from s to e in the object
function setSelection(obj,s,e){
obj.focus();
if (obj.setSelectionRange){
obj.setSelectionRange(s,e);
}else if(obj.createTextRange){
m = obj.createTextRange();
m.moveStart('character',s);
m.moveEnd('character',e);
m.select();
}
}
/* Escape function */
String.prototype.addslashes = function(){
return this.replace(/(["\\\.\|\[\]\^\*\+\?\$\(\)])/g, '\\$1');
}
String.prototype.trim = function () {
return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
};
/* --- Escape --- */
/* Offset position from top of the screen */
function curTop(obj){
toreturn = 0;
while(obj){
toreturn += obj.offsetTop;
obj = obj.offsetParent;
}
return toreturn;
}
function curLeft(obj){
toreturn = 0;
while(obj){
toreturn += obj.offsetLeft;
obj = obj.offsetParent;
}
return toreturn;
}
/* ------ End of Offset function ------- */
/* Types Function */
// is a given input a number?
function isNumber(a) {
return typeof a == 'number' && isFinite(a);
}
/* Object Functions */
function replaceHTML(obj,text){
while(el = obj.childNodes[0]){
obj.removeChild(el);
};
obj.appendChild(document.createTextNode(text));
}
is there any solution for this?
any help will greatly appreciated.
Comment