There are a few functions like actb_godown(), actb_goup(), and actb_penter() which you will have to check if actb_pos is 0. in the case of godown() and goup(), you should prevent the code from reverting the 'original' td element's colour. As for penter(), you will have to stop the script from completing the textbox.
When I put your very nice component near a HTML SELECT (ComboList) the List of the auto complete controle is partially hidden by the HTML Select box ...
I'v not yet find a workaround about this problem, but maybe the solution is explain here : http://www.ozoneasylum.com/8951
This is a known problem with IE. It renders the select boxes on the top of the page elements. Only IFrame objects seem to be rendered over them.
There are two popular solutions to this: 1st is to use an IFrame as the background for the floating element (popup, list, menu...), the 2nd is to dynamically hide all the select boxes when the floated element is being displayed :
---
function hideSelects() {
var selects = document.getElementsByTagName('select');
for (i=0; i
In the microsoft article are you meaning to use an IFRAME or the popup object? Do you have plans to incorporate this into your code? I'm a little unsure about using an iframe in conjuction with your code.
I was evaluating some autocomplete controls and this one was one of the best, so congrats to everyone involved
I've recoded it following an object-oriented approach, so I can have an autocompletion enabled textbox widget in my webapps. I've still to clean up the code quite a lot but I've already shrinked the code quite a few lines and the performance is far better at least in Firefox, plus now it has a propper scroll bar if the number of matches is greater than the specified limit.
It works in IE6, Firefox 1RC and Opera 7.x, I hope it'll work in Safari with a bit of tweaking
Another issue I'll look into is to optimize the current 'string-matching' algorithm by having all the tokens in a huge string (delimited by \n for example) and then we only need to call RegExp once, returning all the matches and storing them in a 'currentMatches' array. I hope it'll be much faster than the current token by token test.
One thing that concerns me is the license in which the code is released. I plan to use this in comercial (profitable) projects and I hope won't be any problems with this, although I prefer to ask first.
I'll ofcourse release the code once it's a bit cleaner and is working with Safari.
After a bit of code tyding I'm at 8.5kb from the 10.2kb of the version I got from a previous post.
I guess another kb can go down by striping the comments.
Opposed to what I thought, using a single string to hold the tokens didn't had a big performance gain. Actually IE is a bit slower using this technique, however the code is much cleaner now, so I'm keeping this method.
I've managed to make it work rock solid on IE5.5, IE6, Firefox 1.0RC and Opera 7.2. IE5 refuses to work due to it's lack of a propper RegEx implementation.
Tomorrow I'll check at work if this runs on Safari and IE:Mac. Once it's working in Safari I'll post a link to download it.
two line change, but it does change your api signature:
function actb_tocomplete(sndr,evt,arr,firstOnly){
actb_firstText = firstOnly;
...
I suppose you could do rename actb_tocomplete to be actb_tocomplete_orig, and add these two functions to preserve your API:
function actb_tocomplete(sndr,evt,arr){
actb_firstText = false;
actb_tocomplete_orig(sndr,evt,arr);
}
function actb_tocomplete_first(sndr,evt,arr){
actb_firstText = true;
actb_tocomplete_orig(sndr,evt,arr);
}
function actb_tocomplete_orig(sndr,evt,arr){
...
In function actb_mouseclick() this.innerText is undefined.
Had to make these changes to get it going:
function actb_mouseclick(){
if (!actb_display) return;
actb_mouse_on_list = 0;
actb_display = 0;
if (undefined != this.innerText) {
actb_curr.value = this.innerText;
} else {
actb_curr.value = striptags(this.innerHTML);
}
actb_removedisp();
}
function striptags(input) {
var chk;
var ret;
chk = input;
ret = input.replace(/<[^>]*>/,"");
while (ret != chk) {
chk = ret;
ret = ret.replace(/<[^>]*>/,"");
}
return ret;
}
Okay, there have been numerous bug-fixes n new functionalities suggested by the users with their code. So, here the download has ALL the functionalities?? I mean the example on the code-project doesn't seem to have those updates features in it!
Other than that, this control looks very kool , Keep up this good work!!
Yes.
I tried to incorporate all changes and to fix a few bugs
This is actb2.js
quote-----------------
/* ---- Variables ---- */
var actb_timeOut = 10000; // Autocomplete Timeout in ms (-1: autocomplete never time out)
var actb_lim = 8; // Number of elements autocomplete can show (-1: no limit)
var actb_firstText = false; // should the auto complete be limited to the beginning of keyword?
var actb_same_size = true; //Should the autocomplete be the same size as the widget (true), or sized based on its elements(false)?
var actb_enable_mouse = true; //Enable mouse support, or just keyboard. Enablingmouse with actb_timeOut set to -1 can cause some unusual behavior.
/* ---- Variables ---- */
/* ---- Constants ---- */
var actb_keywords = new Array();
var actb_display = false;
var actb_pos = 0;
var actb_total = 0;
var actb_curr = 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 mouse_on_list = 0;
/* ---- Constants ---- */
function getTargetElement(evt) {
var elem
if (evt.target) {
elem = (evt.target.nodeType == 3) ? evt.target.parentNode : evt.target;
}
else {
elem = evt.srcElement;
}
return elem;
}
function actb_parse(n,j){//added j to define span id as 'tat_td'+(j)
var t = escape(actb_curr.value);
var tobuild = '';
var i;
if (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 += "<span class='actb_regex_match'";
tobuild += " id='tat_td";
tobuild += (j);
tobuild += "' >";
for (i=p;i<t.length+p;i++){
for (i=p;i<t.length+p;i++){
tobuild += n.substr(i,1);
}
}
tobuild += "</span>";
for (i=t.length+p;i<n.length;i++){
tobuild += n.substr(i,1);
}
return unescape(tobuild);
}
function curTop(){
actb_toreturn = 0;
obj = actb_curr;
while(obj){
actb_toreturn += obj.offsetTop;
obj = obj.offsetParent;
}
return actb_toreturn;
}
function curLeft(){
actb_toreturn = 0;
obj = actb_curr;
while(obj){
actb_toreturn += obj.offsetLeft;
obj = obj.offsetParent;
}
return actb_toreturn;
}
function actb_generate(actb_bool){
if (document.getElementById('tat_table')) document.body.removeChild(document.getElementById('tat_table'));
a = document.createElement('table');
a.className='actb_table';
if (actb_same_size) a.width=field_size;
a.style.top = eval(curTop() + actb_curr.offsetHeight) + "px";
a.style.left = curLeft() + "px";
a.id = 'tat_table';
if (actb_enable_mouse){
a.onmouseover = table_focus;
a.onmouseout= table_unfocus;
}
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
var counter = 0;
for (i=0;i<actb_keywords.length;i++){
if (actb_bool[i]){
counter++;
r = a.insertRow(-1);
if (first && !actb_tomake){
r.className = 'actb_active';
first = false;
actb_pos = counter;
}
else if(actb_pre == i){
r.className = 'actb_active';
first = false;
actb_pos = counter;
}
r.id = 'tat_tr'+(j);
c = r.insertCell(-1);
if (actb_enable_mouse) c.onclick = actb_click_table;
c.innerHTML = actb_parse(escape(actb_keywords[i]),j);
c.id = 'tat_td'+(j);
j++;
}
if (j - 1 == actb_lim && j < actb_total){
r = a.insertRow(-1);
c = r.insertCell(-1);
c.className='actb_arrow_down';
if (actb_enable_mouse) c.onclick = actb_click_down;
c.innerHTML = ' ';
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.className='actb_table';
if (actb_same_size) a.width=field_size;
a.style.top = eval(curTop() + actb_curr.offsetHeight) + "px";
a.style.left = curLeft() + "px";
a.id = 'tat_table';
if (actb_enable_mouse){
a.onmouseover = table_focus;
a.onmouseout = table_unfocus;
}
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
if (actb_rangeu > 1){
r = a.insertRow(-1);
c = r.insertCell(-1);
c.className='actb_arrow_up';
if (actb_enable_mouse) c.onclick = actb_click_up;
c.innerHTML = ' ';
}
for (i=0;i<actb_keywords.length;i++){
if (actb_bool[i]){
if (j >= actb_rangeu && j <= actb_ranged){
r = a.insertRow(-1);
r.id = 'tat_tr'+(j);
c = r.insertCell(-1);
c.innerHTML = actb_parse(escape(actb_keywords[i]),j);
if (actb_enable_mouse) c.onclick = actb_click_table;
c.id = 'tat_td'+(j);
j++;
}
else{
j++;
}
}
if (j > actb_ranged) break;
}
if (j-1 < actb_total){
r = a.insertRow(-1);
c = r.insertCell(-1);
c.className='actb_arrow_down';
if (actb_enable_mouse) c.onclick = actb_click_down;
c.innerHTML = ' ';
}
}
function actb_goup(){
if (!actb_display) return;
if (actb_pos == 1) return;
document.getElementById('tat_tr'+actb_pos).className = '';
actb_pos--;
if (actb_pos < actb_rangeu) actb_moveup();
document.getElementById('tat_tr'+actb_pos).className = 'actb_active';
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(evt.srcElement)",actb_timeOut);
}
function actb_godown(){
if (!actb_display) return;
if (actb_pos == actb_total) return;
document.getElementById('tat_tr'+actb_pos).className = '';
actb_pos++;
if (actb_pos > actb_ranged) actb_movedown();
document.getElementById('tat_tr'+actb_pos).className = 'actb_active';
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(evt.srcElement)",actb_timeOut);
}
function actb_movedown(){
actb_rangeu++;
actb_ranged++;
actb_remake(field_size);
}
function actb_moveup(){
actb_rangeu--;
actb_ranged--;
actb_remake(field_size);
}
function actb_click_table(evt){
evt = (evt) ? evt : ((window.event) ? window.event : "");
if (evt) {
var elem = getTargetElement(evt);
if (elem) {
actb_pos = elem.id.substr(6,50);
mouse_on_list = 0;
actb_penter();
}
}
}
function actb_click_down(evt){
evt = (evt) ? evt : ((window.event) ? window.event : "");
if (evt) {
var elem = getTargetElement(evt);
if (elem) {
actb_pos = elem.id.substr(6,50);
actb_movedown();
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(evt.srcElement)",actb_timeOut);
}
}
}
function actb_click_up(evt){
evt = (evt) ? evt : ((window.event) ? window.event : "");
if (evt) {
var elem = getTargetElement(evt);
if (elem) {
actb_pos = elem.id.substr(6,50);
actb_moveup();
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(evt.srcElement)",actb_timeOut);
}
}
}
function table_focus(evt){
mouse_on_list = 1;
}
function table_unfocus(evt){
mouse_on_list = 0;
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(evt.srcElement)",actb_timeOut);
}
function actb_penter(){
if (!actb_display) return;
actb_display = 0;
var word = '';
var c = 0;
for (var i=0;i<=actb_keywords.length;i++){
if (actb_bool[i]) c++;
if (c == actb_pos){
word = actb_keywords[i];
break;
}
}
a = word;//actb_keywords[actb_pos-1];//document.getElementById('tat_td'+actb_pos).;
actb_curr.value = a;
actb_removedisp();
}
function actb_removedisp(sndr){
if (mouse_on_list == 0 || sndr.value == '') {
actb_display = false;
if (document.getElementById('tat_table')) document.body.removeChild(document.getElementById('tat_table'));
if (actb_toid) clearTimeout(actb_toid);
}
}
function actb_checkkey(evt){
a = evt.keyCode;
if (a == 38){ // up key
actb_goup();
}
else if(a == 40){ // down key
actb_godown();
}
else if(a == 13){//enter key
actb_penter();
}
}
function actb_tocomplete(sndr,evt,arr){
if (arr) {
actb_keywords = arr;
}
if (evt.keyCode == 38 || evt.keyCode == 40 || evt.keyCode == 13) return;
var i;
if (actb_display){
var word = 0;
var c = 0;
for (var i=0;i<=actb_keywords.length;i++){
if (actb_bool[i]) c++;
if (c == actb_pos){
word = i;
break;
}
}
actb_pre = word;//actb_pos;
}
else{
actb_pre = -1;
}
if (!sndr) var sndr = evt.srcElement;
actb_curr = sndr;
field_size = sndr.offsetWidth;
if (sndr.value == ''){
actb_removedisp(sndr);
return;
}
var t = escape(sndr.value);
if (actb_firstText){
var re = new RegExp("^" + t, "i");
}
else{
var re = new RegExp(t, "i");
}
actb_total = 0;
actb_tomake = false;
for (i=0;i<actb_keywords.length;i++){
actb_bool[i] = false;
if (re.test(escape(actb_keywords[i]))){
actb_total++;
actb_bool[i] = true;
if (actb_pre == i) actb_tomake = true;
}
}
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp(sndr)",actb_timeOut);
actb_generate(actb_bool);
}
UNQUOTE-----------------------
and this is actb2.css
QUOTE-----------------------
.actb_table
{
border-right: 1px solid;
padding-right: 2px;
border-top: 1px solid;
padding-left: 2px;
font-size: 11px;
padding-bottom: 2px;
border-left: 1px solid;
cursor: hand;
padding-top: 2px;
border-bottom: 1px solid;
font-family: Verdana;
position: absolute;
background-color: #ffffcc;
border-spacing: 1px;
}
I have it working with multiple words per line but this is the first javascript I have written and it is kinda messy code but if someone wants to re do it more elegantly please do.
basically it takes the input and runs it through the getContents function that checks for ", " in which case it makes a copy of the input string "object" from after the comma to the end of the string. both the object containing the end of the string and the full object are passed to the actb_tocomplete funtion... the variable totalForm is set to the text box input, the autocomplete functions are run on the partial string and when they are returned to the form everything after the last comma "what ever has been typed of the word" is cleared with clearAfter() and replaced with the new word + ", " to make the next autocomplete go when a letter is typed....
html file
--------------------------------------------------
<html>
<head>
<script language="javascript" type="text/javascript" src="actb.js"></script>
<script>
var customarray=new Array('apple','alligator','elephant','pear','kingbird','king bolt','kingcraft','kingcup','kingdom','kingfisher','kingpin');
function copy_obj(o) {
var c = new Object();
for (var e in o) {
c[e] = o[e];
}
return c;
}
function getContents(text)
{
token = ", ";
send = copy_obj(text);
commaPlace = text.value.lastIndexOf(token);
if (commaPlace != -1)
{
start = commaPlace + 2;
end = text.value.length;
val = text.value.slice(start, end);
send.value = val;
return send;
}
actb.js
----------------------------------------------------
/* ---- Variables ---- */
var actb_timeOut = -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)
var actb_lim = 12; // Number of elements autocomplete can show (-1: no limit)
var actb_firstText = true; // should the auto complete be limited to the beginning of keyword?
/* ---- Variables ---- */
/* --- Styles --- */
var actb_bgColor = '#888888';
var actb_textColor = '#FFFFFF';
var actb_hColor = '#000000';
var actb_fFamily = 'Verdana';
var actb_fSize = '11px';
var actb_hStyle = 'text-decoration:underline;font-weight="bold"';
/* --- Styles --- */
/* ---- Constants ---- */
var actb_keywords = new Array();
var actb_display = false;
var actb_pos = 0;
var actb_total = 0;
var actb_curr = 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;
/* ---- Constants ---- */
var totalForm = '';
function actb_parse(n){
var t = escape(actb_curr.value);
var tobuild = '';
var i;
if (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_hStyle)+"'>"
for (i=p;i<t.length+p;i++){
tobuild += n.substr(i,1);
}
tobuild += "</font>";
for (i=t.length+p;i<n.length;i++){
tobuild += n.substr(i,1);
}
return tobuild;
}
function curTop(){
actb_toreturn = 0;
obj = actb_curr;
while(obj){
actb_toreturn += obj.offsetTop;
obj = obj.offsetParent;
}
return actb_toreturn;
}
function curLeft(){
actb_toreturn = 0;
obj = actb_curr;
while(obj){
actb_toreturn += obj.offsetLeft;
obj = obj.offsetParent;
}
return actb_toreturn;
}
function actb_generate(){
if (document.getElementById('tat_table')) 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.offsetHeight) + "px";
a.style.left = curLeft() + "px";
a.style.backgroundColor=actb_bgColor;
a.id = 'tat_table';
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
var counter = 0;
for (i=0;i<actb_keywords.length;i++){
if (actb_bool[i]){
counter++;
r = a.insertRow(-1);
if (first && !actb_tomake){
r.style.backgroundColor = actb_hColor;
first = false;
actb_pos = counter;
}else if(actb_pre == i){
r.style.backgroundColor = actb_hColor;
first = false;
actb_pos = counter;
}else{
r.style.backgroundColor = actb_bgColor;
}
r.id = 'tat_tr'+(j);
c = r.insertCell(-1);
c.style.color = actb_textColor;
c.style.fontFamily = actb_fFamily;
c.style.fontSize = actb_fSize;
c.innerHTML = actb_parse(actb_keywords[i]);
c.id = 'tat_td'+(j);
j++;
}
if (j - 1 == actb_lim && j < actb_total){
r = a.insertRow(-1);
r.style.backgroundColor = actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_fSize;
c.align='center';
c.innerHTML = '\\/';
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.offsetHeight) + "px";
a.style.left = curLeft() + "px";
a.style.backgroundColor=actb_bgColor;
a.id = 'tat_table';
document.body.appendChild(a);
var i;
var first = true;
var j = 1;
if (actb_rangeu > 1){
r = a.insertRow(-1);
r.style.backgroundColor = actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_fSize;
c.align='center';
c.innerHTML = '/\\';
}
for (i=0;i<actb_keywords.length;i++){
if (actb_bool[i]){
if (j >= actb_rangeu && j <= actb_ranged){
r = a.insertRow(-1);
r.style.backgroundColor = actb_bgColor;
r.id = 'tat_tr'+(j);
c = r.insertCell(-1);
c.style.color = actb_textColor;
c.style.fontFamily = actb_fFamily;
c.style.fontSize = actb_fSize;
c.innerHTML = actb_parse(actb_keywords[i]);
c.id = 'tat_td'+(j);
j++;
}else{
j++;
}
}
if (j > actb_ranged) break;
}
if (j-1 < actb_total){
r = a.insertRow(-1);
r.style.backgroundColor = actb_bgColor;
c = r.insertCell(-1);
c.style.color = actb_textColor;
c.style.fontFamily = 'arial narrow';
c.style.fontSize = actb_fSize;
c.align='center';
c.innerHTML = '\\/';
}
}
function actb_goup(){
if (!actb_display) return;
if (actb_pos == 1) return;
document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_bgColor;
actb_pos--;
if (actb_pos < actb_rangeu) actb_moveup();
document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_hColor;
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp()",actb_timeOut);
}
function actb_godown(){
if (!actb_display) return;
if (actb_pos == actb_total) return;
document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_bgColor;
actb_pos++;
if (actb_pos > actb_ranged) actb_movedown();
document.getElementById('tat_tr'+actb_pos).style.backgroundColor = actb_hColor;
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp()",actb_timeOut);
}
function actb_movedown(){
actb_rangeu++;
actb_ranged++;
actb_remake();
}
function actb_moveup(){
actb_rangeu--;
actb_ranged--;
actb_remake();
}
function actb_penter(){
if (!actb_display) return;
actb_display = 0;
var word = '';
var c = 0;
for (var i=0;i<=actb_keywords.length;i++){
if (actb_bool[i]) c++;
if (c == actb_pos){
word = actb_keywords[i];
break;
}
}
a = word;//actb_keywords[actb_pos-1];//document.getElementById('tat_td'+actb_pos).;
//totalForm += a + ",";
//actb_curr.value = totalForm;
clearAfter();
if(totalForm.value != '') totalForm.value += " ";
totalForm.value += a + ", ";
actb_removedisp();
}
function clearAfter(){
//clear everything after last comma
start = 0;
end = totalForm.value.lastIndexOf(",") + 1;
newVal = totalForm.value.slice(start, end);
totalForm.value = newVal;
}
function actb_removedisp(){
actb_display = 0;
if (document.getElementById('tat_table')) document.body.removeChild(document.getElementById('tat_table'));
if (actb_toid) clearTimeout(actb_toid);
}
function actb_checkkey(evt){
a = evt.keyCode;
if (a == 38){ // up key
actb_goup();
}else if(a == 40){ // down key
actb_godown();
}else if(a == 13){
actb_penter();
}
}
function actb_tocomplete(sndr,formObj,evt,arr){
totalForm = formObj;
if (arr) actb_keywords = arr;
if (evt.keyCode == 38 || evt.keyCode == 40 || evt.keyCode == 13) return;
var i;
if (actb_display){
var word = 0;
var c = 0;
for (var i=0;i<=actb_keywords.length;i++){
if (actb_bool[i]) c++;
if (c == actb_pos){
word = i;
break;
}
}
actb_pre = word;//actb_pos;
}else{ actb_pre = -1};
if (!sndr) var sndr = evt.srcElement;
actb_curr = sndr;
if (sndr.value == ''){
actb_removedisp();
return;
}
var t = escape(sndr.value);
if (actb_firstText){
var re = new RegExp("^" + t, "i");
}else{
var re = new RegExp(t, "i");
}
actb_total = 0;
actb_tomake = false;
for (i=0;i<actb_keywords.length;i++){
actb_bool[i] = false;
if (re.test(actb_keywords[i])){
actb_total++;
actb_bool[i] = true;
if (actb_pre == i) actb_tomake = true;
}
}
if (actb_toid) clearTimeout(actb_toid);
if (actb_timeOut > 0) actb_toid = setTimeout("actb_removedisp()",actb_timeOut);
actb_generate(actb_bool);
}
Hi all.
I also added multiply selection feature to the control .
There are only 4 changes in actb.js file
Hope it will be useful for somebody.
actb.js ChangeLog:
1. in Variables section - add
var actb_enable_multiply = 1; //Enable multiply select of values with actb_separator
var actb_separator = ";---;"; //Any Separator string for multiply select
2. in actb_parse function - change
------------------------------------------------------------
// check for multiple select
if (actb_enable_multiply) {
var t_arr = actb_curr.value.split(actb_separator);
if (t_arr.length > 0)
t = escape(t_arr[t_arr.length - 1]);
}
else
var t = escape(actb_curr.value);
------------------------------------------------------------------
instead of
var t = escape(actb_curr.value);
3. in actb_penter function - change
--------------------------------------------------------
// check for multiply select
if (actb_enable_multiply) {
var t_last_index = actb_curr.value.lastIndexOf(actb_separator);
if (t_last_index > 0)
var t_last = actb_curr.value.substring(0,t_last_index+actb_separator.length);
else
var t_last = "";
actb_curr.value = t_last + a + actb_separator;
}
else
actb_curr.value = a;
---------------------------------------------------------
instead of
actb_curr.value = a;
4.in actb_autocomplete function - change
------------------------------------------------------
// check for multiply select
if (actb_enable_multiply) {
var t_arr = sndr.value.split(actb_separator);
if (t_arr.length > 0)
t = escape(t_arr[t_arr.length - 1]);
}
else
var t = escape(sndr.value);
------------------------------------------------------------
I've made a few changes to the widget so that it works with the mouse, and moved the style information out of the js and into a separate CSS file for more flexibility. It turns out the reson the arrow keys won't work in konqueror is because konqueror gives invalid keycodes (0) for the keys, so that's not really fixable. Works great with the mouse in IE, Mozilla, Konqueror, and Safari. Email me if you'd like me to send it to you.
What is the license on this code? May I use it in a BSD licensed project? Thanks for a great widget.
OK, here is a universal diff of the changes, I hope this is a format you can use as the changes are a bit too extensive to just note manually. A few of them are obviously just cosmetic, and a couple are just irrelevant (like making the demo HTML 4.01 compliant). The new css file refers to a couple of images (for the arrows), which I can't attach on these forums. Send me an email with your email address if you'd like a zipfile containing all the files.
Alec
The first entry is just the new css file. The rest are the modifications.
<body>
-<input type='textbox' onkeydown='actb_checkkey(event);' onkeyup='actb_tocomplete(this,event,customarray)' onblur='actb_removedisp()' value=''/>
+
+<input size="35" type="text" onkeydown="actb_checkkey(event);" autocomplete="off" onkeyup="actb_tocomplete(this,event,customarray);" onblur="actb_removedisp(this)" value=""/>
+
</body>
</html>
\ No newline at end of file
diff -urbwN actb_old/actb.js actb_new/actb.js
--- actb_old/actb.js 2004-08-20 15:17:34.000000000 -0700
+++ actb_new/actb.js 2004-09-17 08:15:12.000000000 -0700
@@ -1,18 +1,11 @@
/* ---- Variables ---- */
-var actb_timeOut = -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)
+var actb_timeOut = 1500; // Autocomplete Timeout in ms (-1: autocomplete nevertime out)
var actb_lim = 4; // Number of elements autocomplete can show (-1: no limit)
var actb_firstText = false; // should the auto complete be limited to the beginning of keyword?
+var actb_same_size = 1; //Should the autocomplete be the same size as the widget (true), or sized based on its elements(false)?
+var actb_enable_mouse = 1; //Enable mouse support, or just keyboard. Enablingmouse with actb_timeOut set to -1 can cause some unusual behavior.
/* ---- Variables ---- */
Great control. Maybe this is a form design issue, but ENTER to select the item from the list submits the form (even though there are several more fields I'd like them to submit).
This code handles the ENTER key on forms. I've added it to your JS and it works great (moves focus to next field on enter). Might be good to incorporate into your code... or not.