By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,741 Members | 1,973 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,741 IT Pros & Developers. It's quick & easy.

JavaScript large loop logic on keypress

100+
P: 115
Hi,

Im trying to use javscript to create somthing similar to an autocomplete control inside of javascript. When typing into an input text it loops through a div of available options and selects the closest match. The problem is i have a case where there is over 1000 possible options. If im looping through 1000 options on every keypress things obviously go a little slow.

I have taken as many "." lookups out as i can and use a cached length for the loop.

Any ideas or suggestions?
Sep 29 '08 #1
Share this Question
Share on Google+
6 Replies


iam_clint
Expert 100+
P: 1,208
first suggestion only start the lookup after 3 characters have been entered...
so only start the searching say if they type in cat.


another option place possible search results in an extra div.. so 1 div contains all possible options.. second div contains current matches (less to search through)..

Limit results
Sep 29 '08 #2

gits
Expert Mod 5K+
P: 5,328
additionally it may be, that you could even optimize the loop itself ... show an example of the options and the loop and how this is used to get the matches ...

kind regards
Sep 29 '08 #3

100+
P: 115
first suggestion only start the lookup after 3 characters have been entered...
so only start the searching say if they type in cat.


another option place possible search results in an extra div.. so 1 div contains all possible options.. second div contains current matches (less to search through)..

Limit results
I like the idea of caching the current matches. Let me explain better what im doing. The idea is to replace the IE select box. With the new select box you would be able to type in and it would use each letter you type in to make a match. (IE currently only brings you to the first match of the letter you type, and if you type a second letter it brings you to the first match of that letter. In FireFox when you type the second letter it keeps the first letter and goes to the first match of first letter plus second letter. {thats hard to explain...})

Here is the loop that occurs on key up:

[HTML]function cof_check_match(as_text_id)
{
var l_text = document.getElementById(as_text_id);//Event.element(event);
var l_select = l_text.parentNode;
var ls_id = "i_" + l_select.id;
var l_selectbox = eval(ls_id + ".selectbox");
var l_options = eval(ls_id + ".options");

var ls_original = l_text.value;
var ll_caret = cof_get_caret_pos(l_text)
var lb_match = false;

var ll_go_back = 0;

if( ll_caret > 0)
ls_original = ls_original.substring(0, ll_caret);

var l_option;
var lb_skip;

var ls_text_value;
var ll_text_len;

ls_text_value = l_text.value.toUpperCase();
ll_text_len = ls_text_value.length;

while(!lb_match)
{
for (var j = 0, jl = l_options.length; j < jl; j++)
{
l_option = l_options[j];
lb_skip = false;

if(!lb_match)
{
var ls_text = l_option.innerHTML.toUpperCase();

//See if text is found in list
if(ls_text.startsWith(ls_text_value) && ll_text_len != 0)
{
//Open list if its not open
if (Element.hasClassName(l_select, 'hide-dropdown'))
cof_select_open_dropdown(l_text);

//Scroll to option and set selects value
l_selectbox.scrollTop = l_option.offsetTop;
cof_set_select_value(l_select, l_option);

//Highlight extra text
if (l_text.selectionStart)
{
l_text.selectionStart = ll_text_len;
l_text.selectionEnd = l_text.value.length;
}
else
{
l_txt = l_text.createTextRange();
l_txt.moveStart("character", ls_original.length - ll_go_back);
l_txt.moveEnd("textedit");
l_txt.select();
}

lb_match = true;
break;
}
}
}

if(!lb_match && ll_text_len > 0)
{
ls_text_value = ls_text_value.substring(0, ll_text_len - 1);
ll_go_back++;
}
else
ls_text_value = l_text.value.toUpperCase();

ll_text_len = ls_text_value.length;

if(ll_text_len == 0)
{
l_text.value = l_options[0].innerHTML;
l_text.select();
break;
}
}
}[/HTML]


I alleviated some of the time by replacing the on key up with this:

[HTML] var l_text = Event.element(event);

clearTimeout(i_select_wait);
i_select_wait = setTimeout("cof_check_match('" + l_text.id + "')", 200);[/HTML]
Oct 3 '08 #4

gits
Expert Mod 5K+
P: 5,328
wow ... there's a lot of function calls and dom-operations just for finding matches in a wordlist? function calls and dom-operations are very expensive ones and in case you have much data then this is very bad for performance and even could lead to a message from the browser, that the script could last too long ... i would redesign this code in the following way:

1. on page-load or when loading the options you could create a javascript-object that correspond to this list that should look like this:

Expand|Select|Wrap|Line Numbers
  1. var list_obj = {
  2.     'OPTION_VALUE_OR_INNER_HTML' : option_reference,
  3.     ...
  4. };
2. now you could easyly loop through that obj:

Expand|Select|Wrap|Line Numbers
  1. // create a regExp that ignores case
  2. var re = new RegExp('^' + 'your_chars_that_should_match', 'i');
  3.  
  4. // this array could store all the matching options
  5. var matches = [];
  6.  
  7. // just one efficient loop to get the matching options
  8. for (var i in list_obj) {
  9.     if (re.test(i)) {
  10.         matches.push(list_obj[i]);
  11.     }
  12. }
  13.  
3. now just work with the matches-array to build up the dropdownlist

i assume that you just wanted to show the matching options?

kind regards
Oct 4 '08 #5

100+
P: 115
Thanks for taking the time to reply!

I'm not very experienced with regular expressions (or programming for that matter..) so i tend to forget about them. But i suspect it would be faster than using the toUpperCase & startsWith functions. I actually only want it to return the first ordered match. I was able to speed up a great deal when i changed the way "cof_set_select_value" (not shown) worked as it was looping through the list to unhighlight everything then highlight the selected value. By keeping track of the last item slected i was able to narrow everything down to only the one loop above so now its at least functional. Im gonna rewrite the loop using a regex and see if I can shorten it, then ill post my full results..
Oct 5 '08 #6

gits
Expert Mod 5K+
P: 5,328
the greater performance-boost would come from the shown javascript-object that would represent your word-list so that you just wouldn't need to always retrieve the words from the document ...

kind regards
Oct 5 '08 #7

Post your reply

Sign in to post your reply or Sign up for a free account.