Ajax Auto Suggest v.2

Posted on February 07, 2007

ajax autosuggest

Update 2007-07-19

Version 2.1.3 - demo & guide here.

Download AutoSuggest v.2.1.3

  • Bugfix

Update 2007-07-07

Version 2.1.2

  • Smaller file size (under 9k)
  • Uses encodeURIComponent instead of encodeURI
  • bsn namespace is set as default - uses new bsn.Autosuggest(... instead of new Autosuggest(.... This avoids conflicts with other libraries (e.g. prototype) out of the box.

Update 2007-03-24

I've made a few changes, and shaved off a third of the file size.

Most importantly, using a function as the script variable, it's possible to include values from other fields in your AJAX request. A number of people asked for this functionality.

Compatibility with prototype, and other libraries (version 2.1 and earlier)

Hi to everyone that's having compatibility problems with Prototype or other libraries. Don't write me an email or a comment - here's how to avoid conflict problems:

Before you load the Autosuggest .js, set the following variable in your html page:

useBSNns = true;

This shifts the whole code into the 'bsn' namespace. You then create a new autosuggest as follows:

var as = new bsn.AutoSuggest('idOfTextfield', options);

Undocumented functionality. Sorry.

Tim.

Original post

The new and improved version of my JavaScript/Ajax auto suggest script. More features, less bugs. Demo and documentation here.

Improvements include:

  • Optional JSON Support
  • Callback function support (set ID when user selects list item, or anything else...)
  • Can display more information
  • An optional message when no results are returned
  • Completes field when enter key is pressed
  • Slick new look (2.0 ready!) including fade effect!


Comments (359)

Derek Punsalan said

Nice job with this one. Definitely looks sharp and something to take note of the next time something similar is needed for a side project.

Posted by: Derek Punsalan at February 7, 2007 09:37 AM .

Carlo said

Very nice thank you!

I do have a question:

I have a form with multiple fields which i like to "auto suggest". I've rewritten the test.php so it will query my MySQL database which works nicely. Now when I let the script auto suggest the first field i would like to update the query for the second field of my form. My db consists of up to 2M lines and its growing rapidly. If I could update the SQL statement every time "auto suggest" fills in one of the fields this would narrow down the results.
Is there any way AJAX can grab the content of the first and/or second or... field without submitting the form, or typing or selecting the field(s)?


TIA,

Carlo

Posted by: Carlo at February 7, 2007 02:16 PM .

bsn said

Hi Carlo,

If I understand you correctly, you have to textfields, A and B.
User makes a selection in A.

When she then starts typing in B, you want to pass the value of A as well as the input in B to your server-side script, so you can use two WHERE clauses in your MySQL query.

I'm afraid it's not possible with the current script, because it can only pass hard-coded variables and the input from the current field. I would have to add a custom function that creates the query url... Interesting idea though.

In the meantime, how about saving the first query as a session variable?

Cheers,
Tim.

Posted by: bsn at February 7, 2007 02:34 PM .

Carlo said

Hi Tim,

Yes this was suggested to me already. For now i will use sessions to store them. But it should be possible right? (I'm no AJAX guru). Strange that other people didn't request this option before, I guess other users could use this too.

Anyways, thanks for the tip.

Br,

Carlo

Posted by: Carlo at February 7, 2007 03:23 PM .

Hamilton said

Tks...this script is great...I realy like this because my ASP classic has a perfect work in this script and very easy to use it.

My only problem is ãáíà, my database is in portugues-brazil and this is a problem to work in asp/sql...

but i work on that today and maybe i finish and pot here my solution...tks again and keep working like that...

Posted by: Hamilton at February 8, 2007 07:09 PM .

matteo said

i download files.
I crate my test.aspx
Change the code but i don't see nothing. White page. blank page.
v2 work in other environment???

Posted by: matteo at February 8, 2007 10:49 PM .

xitag said

could you give exemple from mysql database ?

Posted by: xitag at February 8, 2007 11:28 PM .

bsn said

Hi Matteo,

you'll have to change the structure of your xml document. Check the documentation on the example page.

Tim.

Posted by: bsn at February 9, 2007 12:10 AM .

bsn said

Hi Xitag,

I'm afraid that I'm not going to get into the details of retrieving results from a MySQL database here. There's a whole load of issues that have to be addressed, making it difficult to provide a concise example.

Tim.

Posted by: bsn at February 9, 2007 12:36 AM .

matteo said

Another problem.
Impossible to compress javascript.
There are some missing ";"
Can you provide a autosuggest_mini with code compressed?

Posted by: matteo at February 12, 2007 04:27 PM .

Manbeer said

Hi,

We are using .brandspanking "Ajaxauto Suggesion" we have two text box in one page may i know how can we do it

Please help Us

Manbeer

Posted by: Manbeer at February 13, 2007 04:23 PM .

bsn said

Hi Manbeer,

look at the demo page: there are two autosuggest textfields on it.
They need to have unique ids, and you need to create an autosuggest instance for each of them (look at the javascript at the bottom of the HTML source for the demo).

Tim.

Posted by: bsn at February 14, 2007 08:39 AM .

John said

It is sad that Tim doesn't want to supply a (simple) mysql example, does anyone else can supply me an example? I really need it.

John

johnbao at gmail.com

Posted by: John at February 15, 2007 02:33 AM .

MichaelK said

Ahhh, you have it passing the ID value as well now. I remember looking over the first version and I eventually had to make my own because it didn't do this. This would have saved me a bit of time if it was sooner :)
Or perhaps I should have posted my method online for people as well. Maybe if I had more time...
Well done though. For serious applications it should definitely work like this. I wish I could show my work but it's for my company, the autosuggests really do important stuff in what I made. Hehe, I'm an AJAX fool now. I have awesome dynamic stuff all over the place. Thanks for spreading the love :)

Well here's the bit of HTML that will create an autosuggest field in my method. It's pretty slick that you specify all the parameters in the HTML. Notice the parameters... it searches on "client_contact" table for two fields in this case! (it can be just one as well). "name_l" and "name_f".. and will autosuggest if you type 'Smith, John' for example, and the ID returned is called client_contact_id in the client_contact_table. 92 is the maxchars of the textfield (to prevent server load after field is full), 20 is the max number of results in the autosuggest dropdown (and the sql query), ac1_div is the div that's used for the autosuggest results, and the last parameter is the link that each result will have with the dynamic data being at the end as 'client_contact_id=%' and the % is replaced with the ID of that value.

[input type=text name="contact" size="30" maxlength="92" onKeyUp="autocompGen(document.form1.contact.value, 'client_contact', 'name_l%name_f', 'client_contact_id', 92, 20, 'ac1_div', 'view_contact.jsp?user=&case_id=&client_contact_id=%')"]

Posted by: MichaelK at February 15, 2007 03:55 PM .

bohu said

Hi to all,

very nice tool for any application.

I've added some functionality to highlight part of suggestion. you shold add the little part of code to the script to get a highlighting of the suggested result typed into the textbox. Please also add the following lines to in the function

_bsn.AutoSuggest.prototype.setSuggestions = function (req)
after the line:
this.createList(this.aSuggestions);
 
selStart = this.fld.value.length;
selEnd = this.aSuggestions[0]['value'].length;
this.fld.value = this.aSuggestions[0]['value'];
this.selectRange(selStart, selEnd);

And here the new function to add:

//
// Highlight part of text for typeahead
//
_bsn.AutoSuggest.prototype.selectRange = function(iStart, iLength)
{
  if (this.fld.createTextRange) {
    var oRange = this.fld.createTextRange();
    oRange.moveStart("character", iStart);
    oRange.moveEnd("character", iLength - this.fld.value.length);
    oRange.select();
  } else if (this.fld.setSelectionRange)
    this.fld.setSelectionRange(iStart, iLength);

this.fld.focus();
}

It works in FF, IE 6, Opera, Netscape 7.

Godd luck to all,
bohu

Posted by: bohu at February 20, 2007 12:03 AM .

sugarcrm_developer said

What is the current license for distribution? Is there a fee if we were to use code elements in a commercial product? Great Code! Thanks! - E

Posted by: sugarcrm_developer at February 20, 2007 04:05 PM .

cs said

Thanks for this great piece of work.
I would be interested in the support of "dependent" forms as you described them above (A and B), too.
Do you plan to add such a feature?

Posted by: cs at February 20, 2007 05:25 PM .

Matthew said

Wonderful script - looking to customise for my particular site.

The script is looking up street names from a DB. Many of the street names are made up of more than one word. eg TRIQ ABBE R. A. DE VERTOT
This makes matching the first character not very useful.

I have my array populated using LIKE %'.$input.'% which populates the main array properly with the street names based on any part string matching.

However, the rest of your script seems to loose these records and only display those matching the first letter onwards.

Any ideas which functions I need to look at to resolve this? if at all possible.

Thanks! Matthew

Posted by: Matthew at February 25, 2007 08:02 PM .

xSquall said

For those still not figure out how to use it with a simple query to Mysql:

test.php


$input = $_REQUEST['input'];
$link=mysql_connect("localhost", "root", "");
mysql_select_db("YourDateBase",$link);
$qr=mysql_query("SELECT id_user,rut_user FROM tbusers WHERE rut_user LIKE '".$input."%'",$link); while($row=mysql_fetch_array($qr)) { $aResults[] = array( "id"=>($row['id_user']) ,"value"=>htmlspecialchars($row['rut_user']), "info"=>htmlspecialchars($row['rut_user']) );
}
header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header ("Cache-Control: no-cache, must-revalidate"); header ("Pragma: no-cache");
if (isset($_REQUEST['json']))
{
header("Content-Type: application/json");
echo "{\"results\": [";
$arr = array();
for ($i=0;$i {
$arr[] = "{\"id\": \"".$aResults[$i]['id']."\", \"value\": \"".$aResults[$i]['value']."\", \"info\": \"\"}";
}
echo implode(", ", $arr);
echo "]}";
}
else
{
header("Content-Type: text/xml");
echo "";
for ($i=0;$i {
echo "".$aResults[$i]['value']."";
}
echo "";
}


that's all
.

Posted by: xSquall at February 26, 2007 02:53 AM .

Christine said

Hi I am using your script its really good and I came to ask a question, but I notice Carlo already asked it. I want to do the same thing.. I am sure it must be possible, just not quite sure how yet!

If you've had any further ideas on this one, I'd really appreciate it!

Thanks for a great script

Posted by: Christine at February 26, 2007 07:47 AM .

Christine said

Hi again! Further to my comment yesterday, I just wanted to let you know that I figured out a way to do what I wanted.

In the call where you set up which script to use for the database query, I thought what if I could update this when the first text field (in my case suburb) was updated, so I put an onblur event in the suburb field. The onblur then updates options.script, adding an extra url parameter to the end of the script name with the suburb value.

So the onblur on the additional field in my code looks like this:

onblur="options.script='autosuggest/test.cfm?sub=' + this.value + '&';"

I hope I have explained that clearly enough, because it works a treat!

Cheers
Christine

Posted by: Christine at February 27, 2007 03:12 AM .

bsn said

Hi Christine,

sorry I haven't got around to answering - I'm up to my ears in work at the moment.

Good solution!

I would have suggested rewriting the script so that the "script" argument can be either a string (as it is now), or a function. Before the AJAX request is made, you could retrieve a string from the function passed as the script parameter.

if (typeof(script) == "function")
{
    var myscript = script();
} else {
    var myscript = script;
}

// do ajax request using 'myscript'

Your script parameter could look like this:

var script = function () {
    return 'autosuggest/test.cfm?sub='  ¬
        + document.getElementById('field1').value ¬
        + '&';
}

The difference is that the first field doesn't "know" that the second field is grabbing it's value for it's own purposes, whereas in your version the first field actively changes the parameters in the second.

In practice it doesn't make much difference, only that you are relying on logic attached to field1 for the functionality of field2, which somehow doesn't seem so neat.

Tim.

Posted by: bsn at February 27, 2007 08:16 AM .

John said

Hi, very nice script! Is there an 'easy' way to adopt it such that the result list is display upwards instead of downwards?

Posted by: John at February 27, 2007 02:33 PM .

bsn said

Hi John,

after the list has been appended to the DOM (in the createList function), get its offsetHeight, and set the "top" value of the containing div to the y position of the textfield, minus the height of the list, minus any padding you want.

Getting the y position of the text field is a bit tricky, but lucky the script knows it already: pos.y.

div.style.top = pos.y - div.offsetHeight + "px";

Of course, the pointy thingy at the top of the list should then by rights be at the bottom, but that's a CSS issue.

Tim.

Posted by: bsn at February 27, 2007 02:58 PM .

tinytim said

xSquall said

For those still not figure out how to use it with a simple query to Mysql:


anyone else getting this:
Parse error: syntax error, unexpected ';' in /test.php on line 24

any ideas? php noob....

Posted by: tinytim at February 27, 2007 04:09 PM .

bsn said

tinytim

looking at xSqualls code, it looks as if movable type cut out the "less than" symbols in his "for" loops.

Should read:

for (i=0;i<count($arr);i++)

If you copy xSqualls code, there are two things to consider before using it in a live enviornment:

You are pasting your database username and password into a php file. This file should be as closely protected as possible.

You are injecting unvalidated user variables ($_REQUEST['input']) directly into a mysql query. In this example I could search for "!' OR password LIKE '%a'", and mysql would return all users who have password beginning with 'a', presuming a password column exists.

Not exactly hacking the NSA, but it's still a loophole.

If you are using postgreSQL, the engine allows stacked queries, which makes it possible to delete the whole rut_user table in the example, by searching for

"0'; DELETE FROM rut_user WHERE id_user != '0';"

etc. etc.

MySQL security guidelines. Scroll down to "Do not trust any data entered by users of your applications".

Posted by: bsn at February 27, 2007 04:32 PM .

tinytim said

bsn said

tinytim

looking at xSqualls code, it looks as if movable type cut out the "less than" symbols in his "for" loops.

Should read:

for (i=0;i<count($arr);i++)

If you copy xSqualls code, there are two things to consider before using it in a live enviornment:

You are pasting your database username and password into a php file. This file should be as closely protected as possible.

Thanks for the heads up, I usually use a connect
then hide that file...

Posted by: tinytim at February 27, 2007 04:55 PM .

Grateful Developer said

Thank you Tim! Your code rocks (as always)!

Posted by: Grateful Developer at February 27, 2007 11:49 PM .

Christine said

Hi Tim,

Thanks for your comment and the alternative idea you presented. I am not the greatest at JavaScript, but what you say makes perfect sense and I am not a fan of relying on things like onblur, so I will definately try it your way.

Another question, one of the improvements of this version was "Completes field when enter key is pressed" is it possible/easy to make the field complete when tab is pressed, it's just thats how some other autocomplete boxes on our site work and it would be good to keep the consistency.

Cheers
Christine

Posted by: Christine at February 28, 2007 04:56 AM .

Ray Latchmanan said

Hi Tim,
Thank you for all your time you put into helping all of us. ;-)

I am new to AJAX so, would love to get some assistance from you.

I do not have PHP installed on our environment. But I do have an external XML file with all the information. Example below with tags disabled

How can I use that with your script? Any advise will be greatly appreciated.


[?xml version="1.0" encoding="iso-8859-1"?]
[policies]
[policy]
[title]Absenteeism policy[/title]
[url]/hr/pdl/policies/aaaaa.aspx[/url]
[lastupdated]2006-01[/lastupdated]
[/policy]
[/policies]

Cheers,
Ray

Posted by: Ray Latchmanan at February 28, 2007 07:42 AM .

bsn said

Hi Christine,

easy one. line 141. Replace RETURN with TAB.

Tim.

Posted by: bsn at February 28, 2007 10:18 AM .

bsn said

Hi Ray.

Try this (line 306):

// traverse xml
//
var results = xml.getElementsByTagName('results')[0].childNodes;

for (var i=0;i<results.length;i++)
{
if (results[i].hasChildNodes())
{
this.aSuggestions.push( { ¬
'id':results[i].getAttribute('id'), ¬
'value':results[i].childNodes[0].nodeValue, ¬
'info':results[i].getAttribute('info') ¬
} );
}
}


1. Change the value of 'results' to xml.getElementsByTagName('policies')[0].childNodes;. This will give you an array containing the child nodes of policies.

2. The script then loops through the array. For every element that has 'children' (in this case just the 'policy' elements, the whitespace inbetween is ignored), it creates an object and appends it to the aSuggestions array. Each object has an 'id', a 'value', and an 'info' attribute.

You want something like this:

this.aSuggestions.push(  { ¬
  'id':results[i].getElementsByTagName('url')[0].nodeValue, ¬
  'value':results[i].getElementsByTagName('title')[0].nodeValue, ¬
  'info':results[i].getElementsByTagName('lastupdated')[0].nodeValue ¬
}  );

For each policy element ('results[i]'), we retrieve the value of the first (and, in this case, only) 'url' element ('getElementsByTagName('url')[0]'), and assign it as the id of our autosuggest object. We then do the same for the other two elements, assigning them to 'value' and 'info' repsectively.

The value is the main visible field in the autosuggest, and will be pasted into the textfield when the user selects an item from the list.

Tim.

Posted by: bsn at February 28, 2007 10:48 AM .

Meinhard said

Hi bsn,

your script is very cool - thanks a lot!

How can I handle German umlauts with the latest version? My results are coming from mysql and umlauts are stored correct in the database.

Regards,
Meinhard

Posted by: Meinhard at March 1, 2007 02:14 PM .

bsn said

Hi Meinhard,

Umlauts work for me: try typing "Ä" into the textfield in the example.

Tim.

Posted by: bsn at March 1, 2007 02:22 PM .

Ray Latchmanan said

Hi Tim,
Thank for your codes. Do I have to do any changes on this script? As I mentioned above, I don't have PHP or ASP.net. I have an XML file on the same directory as these files.

[code]

var options = {
script:"test.php?json=true&",
varname:"input",
json:true,
callback: function (obj) { document.getElementById('testid').value = obj.id; }
};
var as_json = new AutoSuggest('testinput', options);


var options_xml = {
script:"test.php?",
varname:"input"
};
var as_xml = new AutoSuggest('testinput_xml', options_xml);

[/code]

Posted by: Ray Latchmanan at March 2, 2007 05:34 AM .

Lynx said

Firstly, what a great piece of code. Was just what I was looking for.

I have a little problem I hope someone can help with.

With all the tests and playing around I did before implementing into another script I never once had any problems (so it could be that something from the new script is conflicting).

Any reason why the background is now breaking out from the box.
eg:- www.mypriceguide.co.uk/images/keywordsuggest.png

Any help or solutions would be great.

Many Thanks,
L.

Posted by: Lynx at March 2, 2007 05:51 AM .

Meinhard said

Hi,

you´re right, in your script "Ädams" works fine because in the test.php it´s coded as "Ädams". But in my msql db it would be coded as "Ädams".
"Günter" appears as "G�nter" in the list. Autosuggest finds it, but displays it wrong.

Any ideas?


Meinhard

Posted by: Meinhard at March 2, 2007 07:27 AM .

bsn said

Hi Meinhard,

Try changing the HTML page encoding to ISO-8859-1 (LATIN 1). Test.php is written in UTF-8, which means it looks like "Ädams" when opened as UTF-8 in a text editor...

Tim.

Posted by: bsn at March 2, 2007 07:36 AM .

Meinhard said

Hi Tim,

thanks a lot, now it works fine. :o)


Regards,
Meinhard

Posted by: Meinhard at March 2, 2007 08:51 AM .

Meinhard said

Hi Tim,

another topic confuses me. Please have a look at the two screen shots:
http://www.karsten-jahnke.de/as1.jpg
http://www.karsten-jahnke.de/as2.jpg

I don´t know where to change the color of the small second line of a result. The CSS gives no hint and the java script seems to highlight only the first line of a result.
In your sample script this problem does not appear because the background is nearly black.

What can I do?


Regards
Meinhard

Posted by: Meinhard at March 2, 2007 12:14 PM .

bsn said

Meinhard,

if you read the description on the demo page you'll see the code the script generates to create a list. The second line is in a "small" element. Search for "small" in the CSS file, and you'll find the colours you want to change.

div.autosuggest ul li a span small
{
font-weight: normal;
color: #999;
}

div.autosuggest ul li.as_highlight a span small
{
color: #ccc;
}

Posted by: bsn at March 2, 2007 02:33 PM .

Zagreus said

I've just discovered this useful tool, but I am having problems getting it to work. I have a test form at:

http://telos.london.edu/ajax/journalTitle.html

,which talks to a script which generates XML from a database e.g.

http://telos.london.edu/cgi-bin/lbs/ajaxJT.pl?jt=journal

, but when I type in the journal title form box, I get a browser javascript error which says:

Line: 309
Char: 3
Error: Object Required

I'm new to all this, any advice?

Posted by: Zagreus at March 2, 2007 04:07 PM .

bsn said

Hi Zagreus,

Your XML isn't valid (not sure why), which means the browser can't parse the XML document.

I'll admit that the error handling isn't very good at this juncture.

Tim.

Posted by: bsn at March 2, 2007 04:25 PM .

Zagreus said

Not valid? Does it need to reference a DTD? I have, at the beginning:



ABA BANKING JOURNAL
ABA JOURNAL

etc etc

It looks correct according to the documentation. hmmh.... Maybe I'll try with JSON.

Stephen

Posted by: Zagreus at March 2, 2007 04:39 PM .

bsn said

looks good to me too, but I ran it through a validator, and it didn't like it.

Another thing: I would only return about the first 30 results via AJAX, otherwise the script is going to try to create a list with about 1000 LIs...

Posted by: bsn at March 2, 2007 04:45 PM .

bsn said

Hi Stephen,

I checked the HTTP headers your server is sending, and you have set the Content-Type to "text/xml", not "text/html".

Tim.

Posted by: bsn at March 2, 2007 04:55 PM .

Zagreus said

Thanks for the replies. I've tried both text/xml and text/html - none seem to have any (positive) effect. I think I'm going to have to think about it over the weekend!!

Posted by: Zagreus at March 2, 2007 05:00 PM .

Christine said

Hello yet again Tim!

Thanks again for your quick responses and being soo helpful. I did as you said to make TAB select a list option, however it then makes the TAB key not work when tabbing between the form elements. Any idea how to have both working?

Cheers
Christine

Posted by: Christine at March 6, 2007 01:36 AM .

JosephPhilbert said

How would use this with "php csv2array"??
$dropdowns=csv2array('config/dropdowns/company.csv');

var options = {
script:$dropdown;
varname:"input",
json:true,
callback: function (obj) { document.getElementById('testid').value = obj.id; }
};
var as_json = new AutoSuggest('testinput', options);

want to add it to my current code.


Posted by: JosephPhilbert at March 6, 2007 04:55 AM .

Zagreus said

I've fixed the issue. Initially I was (using perl) doing:

print "Content-type: text/html\n\n";

, changing it to:

print "Content-type: text/xml\n\n";

didn't work, BUT changing it to the following did:

print "Content-type: text/xml; charset=iso-8859-1\n\n";

It needed the charset value set in the header.

I need to play with the presentation now, and also find the best way of using to use the minChars value. I think I'll I play with my script to only start retrieving XML after I've entered the first word, and set shownoresults to false. Obviously if the title is only one word then nothing will happen, but it seems better that retreiving 2000+ records when the person typing j for "journal of whatever", and slowing things down.

Posted by: Zagreus at March 6, 2007 11:46 AM .

bsn said

Hi Zagreus,

You seem to be doing a LIKE '%input%' query. This is far slower than a LIKE 'input%' query. It would be much faster to retrieve only those results whose first characters match the input. Then I would add an index for the first five characters of the 'title' column (if you haven't already). That should speed things up a lot.

Like I said before, I would limit the number of results returned to 30. Displaying 2000 results in a dropdown isn't helping the user.


Tim.

Posted by: bsn at March 6, 2007 11:55 AM .

Zagreus said

Thanks for the advice bsn. One of the reasons I was doing a LIKE '%input%' in my SQL statement, is to cater for journals like:

"the journal of finance"

. Users never put the word "the" in, and hence are surprised when they find nothing. There are ways of getting around this (changing the data etc) - I think I will resort to using the single wildcard (it does speed things up!), and I'll look into the index idea.

Cheers!

Posted by: Zagreus at March 6, 2007 02:23 PM .

Zagreus said

Sorry, this strictly isn't a Ajax Auto Suggest v.2 question, but CSS is not my strong point and this is driving me mad. I have put Auto Suggest into a test form (based on what I actually want to use it for).The url is:

http://telos.london.edu/ajax/afTest.html

The "Journal Title" field is the only field that is is using AA, so if you start typing something like the word "journal", the list of possible values appear. I have two questions:

1. How can I get this to go (float) over the date drop down boxes? At the moment the values seem to go under them, and the date fields prevent the user from seeing the AA values.

2. Is there a way of getting a border around the AA list? I tried something like:

border: 1px solid #888;

, but I get something like:

----
|A|
----
|B|
---
|C|
---

when I want:

----
|A|
|B|
|C|
----

I was hoping that it would appear in a little box, like a drop down list - self contained. Even using border-collapse:collapse, border-bottom:1px doesn't seem to help. Any tips?

I'm editing the "div.autosuggest ul li a" part of the supplied CSS file. Is this the correct section?

Posted by: Zagreus at March 6, 2007 04:42 PM .

Ryan said

I was wondering if it were possible to use this to generate multiple auto completions in the same text box? For instance: you start typing in a name, the auto complete shows up and you click a name, the name is put into to text box followed by a semi-colon, then you start the process over until all the desired names are filled in.

I would like to use this to allow for users to select names in the database, as well as be able to input names which are not in the database. When they submit, the names that aren't in the database would then be added.

I hope this makes sense.

Posted by: Ryan at March 6, 2007 05:39 PM .

Zagreus said

Just in case anyone has the same problem as I had. (re: point one - the drop down div box going under the select box), apparently it's a know problem with certain versions of IE. There's an article here which describes the problem and a possible solution using an iframe:

http://weblogs.asp.net/bleroy/archive/2005/08/09/422047.aspx

Posted by: Zagreus at March 9, 2007 03:41 PM .

Morgan said

I think your .js conflicts with the Ajax.Updater class. The conflict occurs between lines 647 and 662 of your .js. For example, if I remove these lines of code, one of my functions that uses the Ajax.Updater class runs fine, otherwise I get an error about unkown object.

I've spent a few hours trying to make my code compatible with your .js. However, I still can't get your .js and my function to work on the same web document. I have reason to believe the problem lies in the use of XMLHttpRequest and that your .js overrides the attributes and parameters of my embedded javascript.

Posted by: Morgan at March 9, 2007 09:39 PM .

bsn said

Hi Morgan,

Could well be. I can't guarantee that it'll work with every other js. However, try setting the useBSNns variable to true before you load the AutoSuggest file:

<script type"text/javascript">
var useBSNns = true;
</script>

And create a new AutoSuggest instance using the bsn namespace:

var as_json = new bsn.AutoSuggest('testinput', options);

All functions are then encapsulated in an object called "bsn". Might help.

Tim.

Posted by: bsn at March 10, 2007 08:33 AM .

Morgan said

I solved my problem. I basically adapted my script to use bsn's XmlHttpRequest handling only. The problem was that XHR doesn't like multiple instances firing.

Posted by: Morgan at March 10, 2007 08:35 AM .

Morgan said

Thanks bsn! I haven't tried your solution yet but if it works yours is much cleaner than mine :)

I basically passed my XHR variables to your script's XHR handlers and then created an object in your script to output the results to the DOM.

btw, BSN's great! Thanks!

Posted by: Morgan at March 10, 2007 08:41 AM .

GnunuX said

I found some bugs in your code :

1/ In line 294, if I "backspace" all caracters and more when suggest is display, we have a bug.

And my version of ie 5.0 don't understand push method :

---------------------
if (req.responseText != '')
{
var jsondata = eval('(' + req.responseText + ')');

for (var i=0;i {
if (typeof this.aSuggestions.push != "undefined")
{
this.aSuggestions.push( { 'id':jsondata.results[i].id, 'value':jsondata.results[i].value, 'info':jsondata.results[i].info } );
} else {
var new_arr=new Array( { 'id':jsondata.results[i].id, 'value':jsondata.results[i].value, 'info':jsondata.results[i].info } );
this.aSuggestions=this.aSuggestions.concat(new_arr);
}
}
}
---------------------


2/ At the end of "_bsn.AutoSuggest.prototype.clearSuggestions = function ()", in line 609, I have add this line :

---------------------
this.clearHighlight();
---------------------

3/ For ie5, in line 951 I have replace

---------------------
if (this.ele.filters) // internet explorer
---------------------
with
---------------------
if (typeof this.ele.filters != "undefined") // internet explorer
---------------------

and line 951

---------------------
if (this.callback != undefined)
---------------------
with
---------------------
if (this.callback != "undefined")
---------------------

Now this script is bug free (for me) and works fine on ie5.

Just an tipps, at the end of fonction :

_bsn.AutoSuggest.prototype.setHighlightedValue

I have add that :
---------------------
} else {
if (document.getElementById('name_button')) {
document.getElementById('name_button').click();
}
---------------------

Now, when I press enter and there is no suggestion, "name_button" is submit.

I hope it will help some.

Posted by: GnunuX at March 10, 2007 09:11 PM .

boggins said

Fantastic stuff:-) have adapted to autocomplete addresses, the user can then copy address to other parts of form!

One small quirk, on Firefox the id does not seem to return? Ok on Opera and IE. Keep up the good work!

Posted by: boggins at March 11, 2007 11:13 PM .

boggins said

Sorry, forgot to mention, it is happening via Mysql not on your demo! Probably something I have screwed up.

Posted by: boggins at March 11, 2007 11:18 PM .

boggins said

Now sorted. Was using instead of in input tag, doh!

Posted by: boggins at March 12, 2007 09:35 AM .

boggins said

NAME instead of ID

Posted by: boggins at March 12, 2007 09:36 AM .

BPG said

Is it possible to setup autocomple dependency, so that if I, for example search for a supermarket in the first input form the second input form will only autocomple the city’s where it found a supermarket.
So input1 is independent, input2 is depended and autocomplete’s like “Select * from TABLE where supermaked_id=123 and city like “newy%”
I saw something like this was mention before, maybe someone has a example available?
Thanks in advance and success with this GREAT script!

Posted by: BPG at March 12, 2007 11:13 PM .

Nicolas said

hey, this is a really nice script
i've been looking something like thing long ago!!
i have a question
how do i parse a xml with this structure?


NAME
NUMBER


OTHER NAME
OTHER NUMBER


cheers (and excuse my bad english)

Posted by: Nicolas at March 13, 2007 12:59 AM .

Nicolas said

(i have to remember put preview before anything)
now it's right
the question: how do i parse this xml with your nice script?

<row>
<cell>NAME</cell>
<cell>NUMBER</cell>
</row>

<row>
<cell>OTHER NAME</cell>
<cell>OTHER NUMBER</cell>
</row>

</data>
</root>

Posted by: Nicolas at March 13, 2007 01:05 AM .

Nikos said

Hello

I downloaded the script and it is simply awesome. Big thanks. I was wondering, what do I have to do to achieve the following:

-By clicking on my selection, I cause it to execute the following javascript method:

function refresh_uname()
{
var sURL = "index.php?t=tcre&usern="+escape(document.tcreate.username.value);
window.location.href = sURL;
}

Basically, I want to pass the selected value (the field is called 'username') to the URL.

I tried to use a onChange and call the refresh_uname() method but it only takes the incomplete value. For example, if I type 'Ath' and the value in the Bubble is 'Athens' and I click on it, the onChange when I click on the bubble value will get Ath.

Any help as to what to do here is appreciated. Thanks again for this fantastic script...

Posted by: Nikos at March 13, 2007 04:14 PM .

Ernesto Vargas said

I will like to update 4 more fields with values releted to the selection.

Any ideas?

Posted by: Ernesto Vargas at March 13, 2007 10:27 PM .

matteo said

Someone can help me in bringing google address in autosuggest?
would be great if i can make an autosuggest with address of a city. Address that tell me google maps..

someone can help me?

Posted by: matteo at March 14, 2007 03:02 PM .

Richard Zak said

I am trying to use the code, but including it in my CFM file causes an error in another javascript file: "Ajax.Request is not a constructor". Thoughts anyone?

Posted by: Richard Zak at March 14, 2007 08:45 PM .

XaviGo said

Hi.

I'm using your code, I have 2 input text with autosuggest and a select list.
With Mozilla everything works fine but with IE the second autosuggest fields renders *below* the select list so it's almost invisible.

Do you know how can I force the autosuggest to the forefront in IE??

Posted by: XaviGo at March 19, 2007 11:44 AM .

Becky said

What license terms apply to Ajax Auto Suggest?

Posted by: Becky at March 20, 2007 01:16 AM .

bsn said

Hi Becky,

It's released under a creative commons license.

Don't take the attribution part too seriously. If you do use it, and it's feasable to link back to this page (i.e. you're not building whitehouse.gov, or anything like that), I would obviously appreciate it.

Tim.

Posted by: bsn at March 20, 2007 08:09 AM .

Flow said

Hi all,
A repost of using this awesome script with MySQL. I had problems with the one from xSquall so here you go.
Note: I'm using mysqli instead of mysql.
But chanching it back to mysql is a piece of cake.
Note2: This is just the code above the 4 lines that start with "header". Everything from those lines and below is exactly the same.

[code]
$input = strtolower( $_GET['input'] );

$aResults = array();

$link = mysqli_connect("host", "username", "password", "database") or die(mysqli_connect_error());

$query = "SELECT id,straat_off,woonplaats FROM adreslocaties WHERE straat_off LIKE '".$input."%'"." GROUP BY straat_off,woonplaats LIMIT 20;";

$result = mysqli_query($link,$query);

while( $row = mysqli_fetch_array($result) )
{
$aResults[] = array( "id"=>($row['id']) ,"value"=>($row['straat_off']), "info"=>($row['woonplaats']) );
}

[/code]

Posted by: Flow at March 21, 2007 11:51 AM .

Flow said

And ofcourse it has to go into "test.php"

Posted by: Flow at March 21, 2007 11:53 AM .

Flow said

bsn said

Hi Christine,

sorry I haven't got around to answering - I'm up to my ears in work at the moment.

Good solution!

I would have suggested rewriting the script so that the "script" argument can be either a string (as it is now), or a function. Before the AJAX request is made, you could retrieve a string from the function passed as the script parameter.

if (typeof(script) == "function")
{
var myscript = script();
} else {
var myscript = script;
}

// do ajax request using 'myscript'

Your script parameter could look like this:

var script = function () {
return 'autosuggest/test.cfm?sub='  ¬
+ document.getElementById('field1').value ¬
+ '&';
}

The difference is that the first field doesn't "know" that the second field is grabbing it's value for it's own purposes, whereas in your version the first field actively changes the parameters in the second.

In practice it doesn't make much difference, only that you are relying on logic attached to field1 for the functionality of field2, which somehow doesn't seem so neat.

Tim.

I don't get it. Where does this code go?
How does the first or second field know when it is using the script as a string or as a function?
Could someone post the complete script and tell me where I should put it?

I also presume you have to rewrite the test.php file because the query should change.

Posted by: Flow at March 21, 2007 12:15 PM .

Tom said

Thanks for the script - a huge help and time saver.

I'm having a small issue with the 'shownoresults' option of the .JS file. When set to 'false', it still appears to be showing the 'noresult' line. Is there anyway to fix this?

It occurs in the non-modified version of the script I download as well.

Posted by: Tom at March 22, 2007 08:00 PM .

Bogdan said

Hello Tim and thaks for this wonderful script. Great JOB.
Flow said:

I don't get it. Where does this code go?

How does the first or second field know when it is using the script as a string or as a function?

Could someone post the complete script and tell me where I should put it?

I also presume you have to rewrite the test.php file because the query should change.

Hello Flow: you have to find in bsn.AutoSuggest_c_2.0.js this function and replace that code with this:

_bsn.AutoLocalitate.prototype.doAjaxRequest = function ()
{

var pointer = this;

if (typeof(this.oP.script) == "function")
{
var myscript =this.oP.script();
}
else {
var myscript = this.oP.script;
}
// create ajax request
var url = myscript+this.oP.varname+"="+escape(this.fld.value);
var meth = this.oP.meth;

var onSuccessFunc = function (req) { pointer.setSuggestions(req) };
var onErrorFunc = function (status) { alert("AJAX error: "+status); };

var myAjax = new _bsn.Ajax();
myAjax.makeRequest( url, meth, onSuccessFunc, onErrorFunc );
}

Then you have to replace in the html page:
script:"test.php?",
with:
script:function() {
return 'test.php?id='+ document.getElementById('the_field_you_want').value+'&'
},
Hope this helps. Thanks again Tim.
Bogdan

Posted by: Bogdan at March 23, 2007 02:34 PM .

Larry said

Outstanding work Tim... I'm sure you hear that a lot, but it really is a beacon of quality.. :)

I've found the script to be a little slow compared to others... so wondered if it might be the size of the JS code. Is there anything one can cut out to make it a leaner script. I'm using the XML portion exclusively for instance. Does the JSON code make any improvement to performance?

For the PostgreSQL guys... here's my snippet of code for getting 2 fields from the database. Hope it helps:

("header" stuff as normal follows this)

$input = strtolower( $_GET['input'] );
$len = strlen($input);
$aResults = array();

if ($len)
{
$db = pg_connect('your DB');
$qu = pg_query($db, "your QUERY");

$i=0;
while ($row = pg_fetch_row($qu))
{
if (strtolower(substr($row[0],0,$len)) == $input)
{
$aResults[] = array( 'id'=>($i+1), 'value'=>htmlspecialchars($row[0]), 'info'=>htmlspecialchars($row[1]) );
$i++;
}
}
pg_free_result($qu);
}

Posted by: Larry at March 24, 2007 04:51 AM .

Larry said

Is there a quick & easy way for me to populate a second form field with the 'info' result? I don't want a second auto-complete... just have the info line placed into another form input box when the user selects with the mouse or arrows/enter.

A lot of code to look through is daunting, so wondered if you could spare me some! thanks.

Posted by: Larry at March 24, 2007 05:15 AM .

bsn said

Hi Larry,

the JavaScript shouldn't be noticably slower than other scripts. The AJAX request is probably slowing things up. JSON is quicker than XML, because the filesize is smaller (the ratio of markup to data is higher in XML). How many results are you returning from the database? As I've said before, I would limit the number of results to about 30.

As for using the 'info' part: user a callback function:

var options = {
  script:"test.php?json=true&",
  varname:"input",
  json:true,
  callback: function (obj) { document.getElementById('targetField').value = obj.info; }
};

Tim.

Posted by: bsn at March 24, 2007 12:19 PM .

bsn said

@Flo and Bogdan

I've updated the script to do what you're asking for. You can now set the script value as a function, allowing for autosuggest fields that rely on a selection in a previous field.

Tim.

Posted by: bsn at March 24, 2007 03:45 PM .

Nikos said

Tim

Your updated script (the download) seems to appear in one line in a text editor and makes it extremely difficult to read. Is there a way to have this in a format that doesn't appear in one line only? Thanks in advance

Posted by: Nikos at March 26, 2007 12:02 PM .

bsn said

Hi Nikos,

the other javascript file in the js folder is the uncompressed version.

Tim.

Posted by: bsn at March 26, 2007 12:16 PM .

Marco said

Hi Tim,

Thanks for your script. It works great. The mysql tips and the 2 field problem discussion solved a few of my issues.

I still have a question. Is it possible to activate the script when someone tabs to or clicks in the field? I mean before entering a letter.

Thanks Marco

Posted by: Marco at March 26, 2007 03:03 PM .

Timmy said

Thanks for the great script. I set the length for the list is 25 items. However the length of the list is still long. I set the style for the div is scrollable (overflow: auto). When I use the arrow down button, the div is not scrolling. I may not see the highlighted item. How could I make the list scrolling so I could see the highlighted item by using the arrow key?
Thanks so much for your time.

Posted by: Timmy at March 26, 2007 06:13 PM .

Jared said

Hey Zagreus - did you manage to get it working?
Unfortunately for me I can't get that hack working and thus I can't use this script which is a real shame as I spent time integrating it only to find that once I tested it in IE I saw the bug.

I found this post:
http://weblogs.asp.net/bleroy/archive/2005/08/09/422047.aspx

He apparently fixed it, but I can't integrate it as its beyond me.

This auto suggest is the best I've found so it's just a real shame that apart from this stupid IE bug I can't use it.

If anyone nice has managed to integrate a fix, I'd be extremely grateful ;-)

Thanks - J.

Posted by: Jared at March 26, 2007 08:26 PM .

junkie234 said

Hi.

Is there a way to limit the results in the javascript? When I do it in the mysql query and limit something to 5, the code doesnt work the way i need it to. Ex. I'm looking up things that start with number 881, I hit backspace and write 3 instead of the 1, so new results should show up for 883 but its using the same query as for 881 and i get no results.

Can this be modified in the javascript?

Posted by: junkie234 at March 27, 2007 08:43 PM .

Larry said

bsn said

Hi Larry,

the JavaScript shouldn't be noticably slower than other scripts. The AJAX request is probably slowing things up. JSON is quicker than XML, because the filesize is smaller (the ratio of markup to data is higher in XML). How many results are you returning from the database? As I've said before, I would limit the number of results to about 30.

As for using the 'info' part: user a callback function:

var options = {
script:"test.php?json=true&",
varname:"input",
json:true,
callback: function (obj) { document.getElementById('targetField').value = obj.info; }
};

Tim.

Thanks Tim, it worked a treat... I'm only returning 6 results but the DB has 1.5 million records! Needless to say I'm going to work on making the DB smarter first!

By the way, if the JSON is faster, why would someone choose the XML option? Any disadvantages to JSON for instance?

Thanks again,
Larry.

Posted by: Larry at March 28, 2007 06:03 AM .

Martin said

Hi BSN,

thank your for that great script !

Nearly everything works correct for me except the "hidden field" value, if i get the data via xml.

If I use JSON the hidden value shows up, but not with the XML way.

Thats your example form part with an extra hidden field (JS File and CSS Sheet are allready included, 'useBSNns' is allready set to TRUE):
--------------------------------------------------------------------------

<div>
<form method="get" action="">
<small style="float:right">Hidden ID Field: <input type="text" id="testid" value="" style="font-size: 10px; width: 60px;" disabled="disabled" /></small>
<label for="testinput_xml">Person</label>
<input type="text" id="testinput_xml" value="" style="width:300px" />
<br /><br /><input type="submit" value="submit" />
</form>
</div>

And here your Javapart example
--------------------------------

<script type="text/javascript">
var options_xml = {
script: function (input) { return "test.php?input="+input+"&testid="+document.getElementById('testid').value; },
varname:"input"
};
var as_xml = new bsn.AutoSuggest('testinput_xml', options_xml);
</script>


The Dropdown Listing of the People works, but no ID is shown in the hidden field. Did I do something wrong? Is there maybe a bug in the bsn.AutoSuggest_2.1.js file?

Any idea? Hmmm...

Thank you very much for your script and your help !!!

Martin

 

P.S.: Btw.: Is there any way, how I could change the bsn.AutoSuggest_2.1.js file, so that "info" (i.e. Buckinghamshire) and "value" (Altman, Alisha) are both inserted into the textfield after selecting from the dropdown menu (with the dropdown menu staying like it is). Thaaaanks very much.

Posted by: Martin at March 28, 2007 11:47 PM .

Drakkhen said

Hi

I have read all the message from both version and I feel a little stupid.

What I want is really simple.

When the text form has been filled with autosuggest, I just want to submit and go to the page I want with the ID !
How do I decide which ver is transmitted with the form.

thx

Posted by: Drakkhen at March 29, 2007 06:12 PM .

BPG said

Thans again for the great script and the possabilty for dependancy! Unfortunitly i can't get the las one going, can someone please tell me what i;m doing wrong?

// First Field
var options = {
script:"test.php?json=true&",
varname:"input",
json:true,
callback: function (obj) { document.getElementById('testid').value = obj.id; }};
var as_json = new AutoSuggest('testinput', options);
// Second field, dependend onnumber one
var options = {
script: function (input) { return "test.php?json=true&input="+input+"&testid="+document.getElementById('testid').value; },
//script:"test.php?json=true&",
varname:"testen",
json:true,
callback: function (obj) { document.getElementById('testid1').value = obj.id; }};
var as_json = new AutoSuggest('testinput1', options);

Posted by: BPG at March 29, 2007 08:33 PM .

Drakkhen said

@ BGP

If I may.
I have read so much this thread that I know why it won't work.

You initialize twice the same var.
You have to create a different var
//first field
var options1 {...}
var as_json1 = new AutoSuggest('[ID field1]', options1);
// second field
var options2 {...}
var as_json2 = new AutoSuggest('[ID field2]', options2);

Hope it will help you.
If you have an idea for my problem, your welcome ;)

Posted by: Drakkhen at March 30, 2007 09:57 AM .

BPG said

Thanks Drakkhen, it didn't instantly fix my problem, but it got me thinking :o, now I’s fixed :) (also made an error in my PHP code)

Accidently i ran into a solution for your question (I’ll guess be course your question itself isn’t quite clear to me), anyway’s, when I switched the id and type field in the script, on select in auto complete the ‘cityname’ (in my case) was replaced by it’s id in the input field
// options
var options3 = {
script:"autocomplete.php?json=true&",
varname:"wieinput", // “input field”
json:true,
callback: function (obj) { document.getElementById('wieid').value = obj.id; } // “id field”
};
var as_json3 = new AutoSuggest('wieid', options3); // “id field” instead of the usual “input field”
// input field
// my “id field”
//
// my “input field”
//

Posted by: BPG at March 31, 2007 01:31 PM .

zhouxuan said

Hi,

I want to change the style of the result list.The info result is under the user result as default,such as the "Buckinghamshire" is displayed under the "Altman, Alisha" in the Demo page.Now I hope to display these two on one horizontal line,The user result by the left and the info result by the right.How can I do this?Thanks vary much.

Posted by: zhouxuan at April 1, 2007 07:17 PM .

aSeptik said

Hi bsn! ;D

Just little problem! ;D after many times i still have problem to retrieve array from database! i have also tried the xSquall and Flow ways but without result! :(

Can you show me the right way! pls, pls! :D

tnx and good job!


PS: very great script! ;D

Posted by: aSeptik at April 2, 2007 02:15 AM .

Lyubomir Petrov said

Just wanned to note that the design of the box is a lil' buggy in Opera :)

Posted by: Lyubomir Petrov at April 2, 2007 08:51 PM .

Alex said

I have a form with two radio button and a text field.
I would like that the javascript auto-complete from a different php file if one of the radio button is checked.
I tried this but it doesnt work, its always the file1.php that is sendind results, even if bt2 is checked:


if (document.getElementById("bt1").checked == true) {
var options = {
script: "file1.php?",
varname: "input",
json: true
};
} else {
var options = {
script: "file2.php?",
varname: "input",
json: true
};
}
var as = new AutoSuggest('search', options);

any ideas ? plz

Posted by: Alex at April 3, 2007 12:44 AM .

Lee said

Hi BSN,
I posted earlier that I really enjoyed your script but I ran into a problem... I don't see my comment approved though :( My last post was a little lengthy but I'll make it short.

Is there a conflict with Prototype? I get a javascript error when I use both of them together.

Posted by: Lee at April 3, 2007 04:53 AM .

Sanjay said

Hello Everybody,
I have been trying to configure this beautiful piece of code using ASP. But i am getting error.Please have a look at my code and help me. I have replaced opening and closing tags with ( and )

****bsn.AutoSuggest.html****

(html)
(head)
(title)Ajax auto-suggest / auto-complete | BrandSpankingNew(/title)


(script type="text/javascript" src="js/bsn.AutoSuggest_c_2.0.js")(/script)

(link rel="stylesheet" href="css/autosuggest_inquisitor.css" type="text/css" media="screen" charset="utf-8" /)

(/head)
(body)

(div id="wrapper")
(div id="content")

(h2)Example (XML)(/h2)

(div)
(form method="get" action="")
(label for="testinput_xml")Person(/label)
(input type="text" id="testinput_xml" value="" style="width:300px" /)
(br /)(br /)(input type="submit" value="submit" /)
(/form)
(/div)
(script type="text/javascript")


var options_xml = {
script:"test.asp?",
varname:"typing"
};
var as_xml = new AutoSuggest('testinput_xml', options_xml);
(/script)

(/body)


****test.asp****
(%
typing = LCase(Request("typing"))

Set objconn=server.createobject("adodb.connection")
objconn.open "Provider=sqloledb;Server=Servername;Database=DBName;UID=sa;PWD=pwd;"
set objrecord=server.createobject("adodb.recordset")


set objrecord=objconn.execute("SELECT TOP 10 records FROM tablename WHERE CHARINDEX ('"&typing&"', records)) 0 ORDER BY CHARINDEX ('"&typing&"', records)")

if objrecord.eof or objrecord.bof then

Response.Write "Oops Not Found"
response.end
else

end if

Response.ContentType = "text/xml"

Response.write "(?xml version=""1.0"" encoding=""utf-8"" ?)(results)"
do while not objrecord.eof
i=i+1
Response.write "(rs)"&objrecord.fields("Vilname")&"(/rs)"
objrecord.movenext
loop
Response.write "(/results)"

%)

Posted by: Sanjay at April 3, 2007 09:28 AM .

Harrison said

Hi, BSN.. Your script really help me a lot in my project, I would like to say thank on your efforts :-)

Well, I have another small question, if wnat the script do something when visitor click and select a choice from the drop down list? for example loading a product information?

One more thing, may I know what is the hidden ID use for?

Thank you

Posted by: Harrison at April 7, 2007 06:38 AM .

h4bib said

Is there a conflict with Prototype? I get a javascript error when I use both of them together....

:(

what to do?

Posted by: h4bib at April 10, 2007 04:09 PM .

angel said

Hi,

I would like to suggest to use encodeURI() instead of escape() function for creating the HTTP request.
The escape() doesn't convert characters like 'ý' to unicode.

angel

Posted by: angel at April 13, 2007 01:01 AM .

Almas said

I've created a scrolling auto-suggest box (div).

file: bsn.AutoSuggest_c_2.0.js,
in "_bsn.AutoSuggest.prototype.createList = function(arr) {}"

add these lines after "div.style..." lines:
div.style.height = "100px";
div.style.overflow = 'auto';

and replace "_bsn.AutoSuggest.prototype.changeHighlight = function(key) {}" function with this:

_bsn.AutoSuggest.prototype.changeHighlight = function(key)
{
var list = _bsn.DOM.getElement("as_ul");
var div = _bsn.DOM.getElement(this.idAs);

if (!list)
return false;

var n;

if (key == 40)
n = this.iHighlighted + 1;
else if (key == 38)
n = this.iHighlighted - 1;

if (n > list.childNodes.length)
n = list.childNodes.length;
if (n n = 1;

if (key == 40 && n > 1)
div.scrollTop = div.scrollTop + list.childNodes[n-1].scrollHeight;
else if (key == 38 && n div.scrollTop = div.scrollTop - list.childNodes[n-1].scrollHeight;

this.setHighlight(n);
}

Then if you hit down or up arrow your auto-suggest box will scroll up and down.

Posted by: Almas at April 14, 2007 10:56 PM .

satya said

thanks for writing a very nice code .
it is working on Firefox and IE when i use
html
only here some code for auto
html
but i am using W3C ORG standard like
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
html xmlns="http://www.w3.org/1999/xhtml"
here some code for auto suggest
html
then it isnot working on IE good way .

problem is Div create space between to div and remove.

Can u please tell ywhy it create space in between div.

Thnkas in advance.

Posted by: satya at April 18, 2007 07:33 AM .

Leo said

Hi, firstly this is a brilliant piece of coding. Thanks a lot.

I have managed to get it set up and working perfectly in firefox but when i try it in safari nothing shows up at all. Any ideas what may be causing this?

the code i use is:


var options = {
script: "auto.php?",
varname: "input",
};
var as = new AutoSuggest('searchInput', options);

If you can help i will be eternally gratefull

cheers

leo

Posted by: Leo at April 20, 2007 10:46 PM .

Jean said

I too think this is a great script, but I have the same problem as some others do, it isn't compatible with other prototype dependent scripts.

It starts at/around line 623 (not sure the exact line, as I made some changes myself).

"// AJAX PROTOTYPE".

I think the problem is that you use _bsn.Ajax to create prototype functions. This way it "overwrites" the use of Ajax.Request for example.

I'm narrowing down the error and see if I can fix it myself, but I'm no JS guru, I'm just a PHP programmer who likes to get involved in the "client side hype" :)

Posted by: Jean at April 21, 2007 12:16 AM .

Jean said

Well, that went a lot faster than I expected. To all those who have the same problem as I described in my above post, just rename all instances of _bsn.Ajax to something like _bsn.Ajax2...

Posted by: Jean at April 21, 2007 12:21 AM .

bsn said

Hi Jean, and to everyone that's having compatibility problems with Prototype or other libraries: You can solve the problem even faster.

Before you load the Autosuggest .js, set the following value to 'true':

useBSNns = true;

This shifts the whole code into the 'bsn' namespace. You then create a new autosuggest as follows:

var as = new bsn.AutoSuggest('idOfTextfield', options);

Undocumented functionality. Sorry.

Tim.

Posted by: bsn at April 21, 2007 08:25 AM .

bsn said

@Leo:

the extra comma after "input", perhaps?

Tim.

Posted by: bsn at April 21, 2007 08:26 AM .

Ebrahim said

Hi, I have used the code and it was complete and without any lack.

But as I've used it with my own css file there was problems in the whole structure,for example not showing the

  • s correctly and all the view is not suitable,
    It may not mean of ajax or javascript, my problem is with css files and I want to ask if is it possible to make the css tags specially for the textbox and not active for the other parts of the page.
  • thanks alot

    Posted by: Ebrahim at April 21, 2007 09:16 AM .

    Jean said

    I'm having trouble getting the json structure to show correctly. The document says it should look like:

    { results: [
    	{ id: "1", value: "Foobar", info: "Cheshire" },
    	{ id: "2", value: "Foobarfly", info: "Shropshire" },
    	{ id: "3", value: "Foobarnacle", info: "Essex" }
    ] }
    

    but when I look in firebug I get these results (look at the unwanted quotes):

    {"results": [{"id": "1", "value": "Jean Mertz", "info": ""}, {"id": "47", "value": "Jenkins, Merrill"
    
    

    , "info": ""}]}

    I'm not sure if this is a problem, since the results are still shown, but when I select a name from the list it parses the ID in the textfield, instead of the VALUE. I checked the JS but couldn't find anything. Any suggestions?

    Posted by: Jean at April 21, 2007 12:54 PM .

    Jean said

    On top of my previous question, would it be possible to make the first found autosuggest snap to the onkeydown for the ENTER/RETURN key?

    When using this nifty script my feeling always makes me hit enter whenever I have the desired result on the first place, however, right now you have to click on it or hit the arrow-down key first to select it.

    Posted by: Jean at April 21, 2007 01:19 PM .

    Lee said

    Hi,
    Does anyone know how to make the autosuggest width a little bigger? My input field is kind of small, and so I would want the width to be about 200%.

    Along those lines--has anyone made any other sets of CSS rules for the autosuggest? I really like the CSS as it is, but it doesn't match my own scheme.

    Thanks!

    Posted by: Lee at April 21, 2007 08:33 PM .

    Jean said

    Lee,

    Look around the line 440 for this comment:

    // get position of target textfield
    // position holding div below it
    // set width of holding div to width of field

    You'll find your answers there ;)
    Also, about the css styles. I made mine a bit more simplistic and less intrusive. (click)

    Posted by: Jean at April 22, 2007 12:27 AM .

    Ebrahim said

    I can't use it in combination of other CSS files,
    how can i preform it to be applicable with every file,
    How can i use it with different CSS file and not mixed with my other HTML element?

    thanks

    Posted by: Ebrahim at April 22, 2007 03:55 PM .

    Lee said

    Jean, that worked perfectly, thanks!

    I changed the left boundary and width accordingly. I wonder if I could introduce more options that could be used like this.oP.offsety in the excerpt below?


    // get position of target textfield
    // position holding div below it
    // set width of holding div to width of field
    //
    var pos = _bsn.DOM.getPos(this.fld);

    div.style.left = (pos.x-this.fld.offsetWidth/2) + "px";
    div.style.top = ( pos.y + this.fld.offsetHeight + this.oP.offsety ) + "px";
    div.style.width = (this.fld.offsetWidth*2) + "px";

    Posted by: Lee at April 23, 2007 06:16 AM .

    namotco said

    I have a form with the ability to dynamically add more text boxes. How can I use auto suggest with them?

    Posted by: namotco at April 24, 2007 01:24 AM .

    namotco said

    How can I make it work with a text area?

    Posted by: namotco at April 24, 2007 07:49 PM .

    George Verras said

    Hi Tim,
    I adapted your AS V2 code to work with my legacy ASP app. It is Wonderful!! I am using it to create a list, limited to 10 rows of the names of Client Offices that match the textbox input. I'm using SQL Server on the back end to provide an XML data stream back to the AJAX control. Works like a charm! ( I would be happy to share with anyone how I did this) I did find this little bug... because I'm