Link to home
Start Free TrialLog in
Avatar of RecipeDan
RecipeDan

asked on

Autocomplete

Hello:

I have this autocomplete dropdown box. What is occuring is when I select the team, the team name gets passed not the Team ID. Is there a way to get the Team ID value passed?

		<select style="text-transform:uppercase" name="TeamOption" onfocus="Teamname.value=''" onkeypress="if(document.all){return gc('TeamOption','Teamname',window.event.keyCode)}" tabindex="6">
		<option></option>
		<%
		Do While Not rs.EOF
		%>
		<option value="<%=rs("TeamID")%>"><%=rs("Team")%></option>
		<%
		rs.MoveNext
		Loop
		%>
		</select>
		<input type="hidden" name="Teamname" />

Open in new window

<script language="javascript">
function gc(selectit,hideit,char){
      char=String.fromCharCode(char).toUpperCase()
      hideit=eval("document.forms[0]."+hideit)
      selectit=eval("document.forms[0]."+selectit)
      hideit.value+=char
      i=selectit.selectedIndex
      while(i<selectit.options.length){
          if(selectit.options[i].innerText.toUpperCase().indexOf(hideit.value)==0){
               selectit.selectedIndex=i
               i=selectit.options.length+1
          }
          i++
      }

      if(i==selectit.options.length+2){return false}
            else{hideit.value=char;return true}
}


</script>

Open in new window

Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

I am confused - a drop down will auto seek to the item based on the letter you type.

If you submit the form the teamid for the selected item will be passed back.

What is the purpose of the code above?
Hi,
another question:
How about using jQuery UI autocomplete?
@RainerJ - he will still have the same problem. the JQueryUI is going to pass back the item selected not the id.

You have to put in an involved helper to get the id to be passed back.
get the value of id attribute of the selected item:

hideit.value = selectit.selectedIndex.getAttribute("id");
here's an example:

<!DOCTYPE html>
<html>
  <head>
    <title></title>
    <meta charset="UTF-8">
    <script>
        window.onload = function(){
        teamname = document.forms[0].elements['Teamname'];
        }
    </script>
  </head>
  <body>
      <form>
     		<select name="TeamOption" id="me" onchange="teamname.value = this.options[this.selectedIndex].getAttribute('id');" tabindex="6">
		<option id="0">saints</option>
		<option id="1">bulls</option>
                <option id="2">devils</option>
                <option id="3">kyles</option>
		</select>
		<input type="text" name="Teamname" />
      </form>
  </body>
</html>

Open in new window

Avatar of RecipeDan
RecipeDan

ASKER

@ kozaiwaniec:

The above code works. I am pulling the values from a database so when I put this piece of code in, it does not work.

		<%
		Do While Not rs.EOF
		%>
		<option value="<%=rs("TeamID")%>"><%=rs("Team")%></option>
		<%
		rs.MoveNext
		Loop
		%>

Open in new window

sorry, change the attribute "id" to "value"


here's a modified version:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <script>
            window.onload = function(){
                teamname = document.forms[0].elements['Teamname'];
            };
            function getIdofSelected(list){
                return list.options[list.selectedIndex].getAttribute('value');
            };
            function setValue(field, list){
                field.value = getIdofSelected(list);
            };
        </script>

    </head>
    <body>
        <form>
            <select name="TeamOption" id="me" onchange="setValue(teamname, this);" tabindex="6">
                <option value="0">saints</option>
                <option value="1">bulls</option>
                <option value="2">devils</option>
                <option value="3">kyles</option>
            </select>
            <input type="text" name="Teamname" />
        </form>
    </body>
</html>

Open in new window

It does not work. For example when I type Browns. When I type the "W" it goes to the W's

        <script>
            window.onload = function(){
                teamname = document.forms[0].elements['Teamname'];
            };
            function getIdofSelected(list){
                return list.options[list.selectedIndex].getAttribute('value');
            };
            function setValue(field, list){
                field.value = getIdofSelected(list);
            };
        </script>

Open in new window

		<select style="text-transform:uppercase" name="TeamOption" id="me" onchange="setValue(Teamname, this);" tabindex="6">
		<option></option>
		<%
		Do While Not rs.EOF
		%>
		<option value="<%=rs("TeamID")%>"><%=rs("Team")%></option>
		<%
		rs.MoveNext
		Loop
		%>
		</select>
		<input type="hidden" name="Teamname" />

Open in new window

not sure what you mean.

When I type the "W" it goes to the W's
isn't that what you would want?

What happens when you type Browns?

could you post the output of the asp loop?
you could try focusing the select list on load - but I'm nor really clear as to what Im trying to fix :)

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <script>
            window.onload = function(){
                teamname = document.forms[0].elements['Teamname'];
                document.forms[0].elements['TeamOption'].focus();
            };
            function getIdofSelected(list){
                return list.options[list.selectedIndex].getAttribute('value');
            };
            function setValue(field, list){
                field.value = getIdofSelected(list);
            };
        </script>

    </head>
    <body>
        <form>
            <select name="TeamOption" id="me" onchange="setValue(teamname, this);" tabindex="6">
                <option value="0">saints</option>
                <option value="1">bulls</option>
                <option value="2">devils</option>
                <option value="3">kyles</option>
            </select>
            <input type="text" name="Teamname" />
        </form>
    </body>
</html>

Open in new window

OK....Here is an example how my loop looks like

                <option></option>
                <option value="4">Bears</option>
                 <option value="6">Browns</option>
                <option value="7">Bulldogs</option>
                <option value="9">Champs</option>
                <option value="11">Cubs</option>
                <option value="34">Whiz Kids</option>
                <option value="42">Zebras</option>

When I type Browns, once I press W it goes to Whiz Kids.
That's exactly what you would expect. why are you pressing W?
OK, I think I see what you're trying to do. As you type B-R-O-W- it skips to Whiz-kids... and you don't want it to do that, hence you're trying to circumvent the default behaviour.

But Why? That's what people are used to. And honestly, a select box isn't usually used with keystrokes, it's used by selecting items with the mouse.
Also, once Browns appears as the selected item, a person will stop typing.

The person who is looking down at their keyboard as they type, is most likely going to use their mouse on a select list anyway.
Yes....that is what I am trying to do. Honestly, it is not my project. I created this for a group of volunteers who have to enter large amounts of data. I was told from a data entry standpoint it would make it easier it they can type the word instead of trying to find it from a list.

What would you suggest I do? The volunteers have different computer abilities so I am trying to keep it easy as possible and reduce data entry errors.
That's why it's kind of nice that all you have to do is type the first letter or two, and your item comes up. However from an entry error perspective you have a point...

let me think about it... I'll get back to you.
What you actually want is a bit more complicated to do and although I said there were issues with it I think RainerJ's post above might be more feasible here.

Take a look at the jqueryui at jqueryui.com. You are still going to have the problem that the id value is not going to be submitted.

There are two workarounds for this

1. Make the display value the key and either find the id server side based on the value submitted
2. Refer to these links on a workaround

http://stackoverflow.com/questions/4866699/jquery-ui-autocomplete-with-values

Which refers here for a soluti0n

http://jsfiddle.net/dhoerster/BXYpt/
You can avoid the issue by making it a multi select box.

You do not need to load jQuery for a simple js operation. Also, the example above uses an input field, so if the user doesn't what their options are, they will be completely lost.

here's a revised solution:

   
 <head>
        <title></title>
        <meta charset="UTF-8">
        <style>
            
        </style>
        <script>
            window.onload = function(){
                teamname = document.forms[0].elements['Teamname'];
                document.forms[0].elements['TeamOption'].focus();
            };
            function getIdofSelected(list){
                return list.options[list.selectedIndex].getAttribute('value');
            };
            function setValue(field, list){
                field.value = getIdofSelected(list);
            };
        </script>

    </head>
    <body>
        
        <form>
            <select name="TeamOption" id="me" onchange="setValue(teamname, this);" tabindex="6" multiple="multiple">
                <option value="4">Bears</option>
                 <option value="6">Browns</option>
                <option value="7">Bulldogs</option>
                <option value="9">Champs</option>
                <option value="11">Cubs</option>
                <option value="34">Whiz Kids</option>
                <option value="42">Zebras</option>
            </select>
            <input type="text" name="Teamname" />
        </form>
        
     
    </body>
</html>

Open in new window

http://candpgeneration.com/EE/getValue.html
@kozaiwaniec
. Also, the example above uses an input field, so if the user doesn't what their options are, they will be completely lost

This is why I recommend the jqueryui because what is required is not just a few lines of javascript.

Take a look at the combobox sample of the JQueryUI autocomplete

http://jqueryui.com/demos/autocomplete/#combobox
To use the combo-box solution you would need to load over 250kb of extra code (that's all scripts minimized and only the custom required ui widgets), and add three http requests to your page. You will still need to customize it to return the value of the option selected.

If you use a multi-select box, you will be achieving essentially the same result with 10 lines of plain javascript. Granted it's not exactly the same, you have to keep in mind the overall picture. What's more important to your client(s) - performance or a fancy ui?
All I am saying is the post is titled "Autocomplete"

And the author specifically states
I was told from a data entry standpoint it would make it easier it they can type the word instead of trying to find it from a list.

Other alternatives have been posted which did not seem to match.

250Kb - for a once off download is the size of a large image on a site. Personally I am not a big fan of bloat and will be the first to do the few lines of JScript before downloading a library - but the bottom line is the requirement has been stated and the multi-select does not cut it - hence the recommendation for an alternative which does meet the requirement.
not sure how it doesn't meet the requirement - when the user starts typing the appropriate option is highlighted. That meets the requirement.

250Kb - for a once off download is the size of a large image on a site
Why download something the size of a large image?
If you want, you can also use your original code, with some modifications to capture the value:

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <meta charset="UTF-8">
        <style>
            
        </style>
        <script language="javascript">
            function gc(selectit,hideit,charc){

                charc=String.fromCharCode(charc).toUpperCase();
                hideit=eval("document.forms[0]."+hideit);

                selectit=eval("document.forms[0]."+selectit);


                hideit.value= selectit.options[selectit.selectedIndex].getAttribute('value');

                i=selectit.selectedIndex;
                while(i<selectit.options.length){
                    if(selectit.options[i].innerText.toUpperCase().indexOf(hideit.value)==0){
                        selectit.selectedIndex=i
                        i=selectit.options.length+1
                    };
                    i++
                };

                if(i==selectit.options.length+2){return false}
                        else{
                            hideit.value = selectit.options[selectit.selectedIndex].getAttribute('value');
                            return true
                        };
            };

</script>

    </head>
    <body>
        
        <form>
            <select style="text-transform:uppercase" name="TeamOption" onchange="gc('TeamOption','Teamname',window.event.keyCode);" tabindex="6">
                <option value="4">Bears</option>
                 <option value="6">Browns</option>
                <option value="7">Bulldogs</option>
                <option value="9">Champs</option>
                <option value="11">Cubs</option>
                <option value="34">Whiz Kids</option>
                <option value="42">Zebras</option>
            </select>
            <input type="text" name="Teamname" />
        </form>
        
     
    </body>
</html>

Open in new window

I guess you could argue why download anything (stylesheets, images, movies etc). We are moving into a space where interactive sites are the norm and to provide that functionality requires code ...

But I am not going to argue with you - that is my recommendation
The argument is why download UNNECESSARY code.
Having said that - nice code - not as flashy as the JQUI version but nice and compact and the effect is the same.
:)) - can't take all the credit, it's mostly the original js.

such fun and games!
After reading everything about jQuery, even though it requires more lines. I think in terms of data entry, its more appropriate. However, one of the drawbacks for me, is that in most of the examples the code is in PHP to get the values from the database. I am assuming because JSON is easier to manipulate in PHP. The problem is I don't know PHP.

How would you convert this code to ASP?

<?php

	//connection information
	$host = "localhost";
	$user = "root";
	$password = "your_password_here";
	$database = "test";
	$param = $_GET["term"];
	
	//make connection
	$server = mysql_connect($host, $user, $password);
	$connection = mysql_select_db($database, $server);
	
	//query the database
	$query = mysql_query("SELECT * FROM friends WHERE name REGEXP '^$param'");
	
	//build array of results
	for ($x = 0, $numrows = mysql_num_rows($query); $x < $numrows; $x++) {
		$row = mysql_fetch_assoc($query);
    
		$friends[$x] = array("name" => $row["name"]);		
	}
	
	//echo JSON to page
	$response = $_GET["callback"] . "(" . json_encode($friends) . ")";
	echo $response;
	
	mysql_close($server);
	
?>

Open in new window

The solution would depend on how you are going to be sending data back. Are you going to be sending back from a database in which case which one (MySQL / MS SQL / Oracle / Other)?

Are you using ASP classic or ASP.NET
Yes I am using a SQL Database with Classic ASP
Do you need a direct translation of the code or are you familiar enough with ASP to follow this

Lines 1-12 are establishing a link to the db so you would do something like this.

My database is called terms and is defined as follows
id AutoNumber Primary Key
Term text(50)

<%
  set cn = server.createobject ( "ADODB.Connection" ) 
  cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=E:\temp\test.mdb"
  cn.Open

  sql  = "SELECT * FROM terms WHERE term LIKE '" & Request("term") & "%'"
  set rs = cn.Execute(sql)
  if not rs.EOF then
    rs.MoveFirst
    strJson = "{" & Chr(10)
    strjson = strjson & """results"": [" & Chr(10)
    count = 1
    while not rs.EOF
       if (count > 1) then 
         strjson = strjson & "," & Chr(10)
       end if
       strjson = strjson & "{ ""name"":""" & rs("term") & """}"
       count = count + 1
      rs.MoveNext
    wend
    strjson = strjson & Chr(10) & "]" & Chr(10)
    strjson = strjson & "}" & Chr(10)
  end if
  Response.Write strjson
%>

Open in new window

Here is sample code for connecting to it
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
	$('#select').keyup(function() {
		$.getJSON('test2.asp?term=' + $('#select').val(), function(data) {
			console.log(data);
		}, 'json');
	});
});
</script>
</head>
<body>
Input here <input type="text" name="term" id="select" />
</body>
</html>

Open in new window

Hello:

The Code is not working. Here is what I have:

Test.asp
<!doctype html>
<html>
<head>
<title>Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
	$('#select').keyup(function() {
		$.getJSON('test2.asp?term=' + $('#select').val(), function(data) {
			console.log(data);
		}, 'json');
	});
});
</script>
</head>
<body>
Input here <input type="text" name="term" id="select">
</body>
</html>

Open in new window


test2.asp
<%
Set rwbconn = Server.CreateObject("ADODB.Connection")
Set rs = Server.CreateObject("ADODB.Recordset")
conn.Open "Driver={SQL Server};" & _ 
           "Server=DataServer;" & _
           "Database=TeamsTable;" & _
           "Uid=Joe23;" & _
           "Pwd=W753"
%>
<%
  sql  = "SELECT * FROM terms WHERE term LIKE '" & Request("term") & "%'"
  set rs = conn.Execute(sql)
  if not rs.EOF then
    rs.MoveFirst
    strJson = "{" & Chr(10)
    strjson = strjson & """results"": [" & Chr(10)
    count = 1    while not rs
.EOF
       if (count > 1) then 
         strjson = strjson & "," & Chr(10)
       end if
       strjson = strjson & "{ ""name"":""" & rs("term") & """}"
       count = count + 1
      rs.MoveNext
    wend
    strjson = strjson & Chr(10) & "]" & Chr(10)
    strjson = strjson & "}" & Chr(10)
  end if
  Response.Write strjson
%> 

Open in new window


I created a table and put a list of teams in to test it.
              AutoID       Term
	1	Angels
	2	Bulls
	3	Bears
	4	Cubs
	5	Mets
	6	Whiz Kids
	7	Zebras
	8	Lions
	9	Tigers
	10	Bullbogs
	11	Devils
	12	Bowns
	13	Indians
	14	Superstars
	15	Whites
	16	Blues
	17	Ponies

Open in new window

When you say not working are you getting an error?
Not I am not getting a specific error message. I start typing the name in the input box and I get no choices.
Do you have firebug installed with FireFox ?

If so you can go to the script console (right click -> inspect element then click the console tab) and see if there are any script errors.

In IE look for the yellow triangle bottom left.

The test code does work - will look at it again tomorrow and feedback.
I checked all the settings and permissions on the SQL Server and everything is fine. I am using Internet Explorer. There is no error message.
OK...I get an error message.


Message: 'console' is undefined
Line: 10
Char: 4
Code: 0

<script type="text/javascript">
$(function() {
	$('#select').keyup(function() {
		$.getJSON('test2.asp?term=' + $('#select').val(), function(data) {
			console.log(data);
		}, 'json');
	});
});
</script>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I removed the line and nothing happens.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
	$('#select').keyup(function() {
		$.getJSON('test2.asp?term=' + $('#select').val(), 'json');
	});
});
</script> 

Open in new window


I ran a JSON Outpatient on test2.asp. It looks like the output is correct.
{ "results": [ { "name":"Browns"} ] } 

Open in new window