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
Expand|Select|Wrap|Line Numbers
- //////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;
- }
Expand|Select|Wrap|Line Numbers
- /* 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.