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

Autocomplete better

100+
P: 769
Hey Everyone,

Right now i have a script where when someone starts typing in the input field that it populates the drop down box next to it. Once both the input and drop down box have the same number then it autofills the rest of the form. This works great. But now i have realized that lets say i have a previous entry of a00092 but i am creating a new entry an it is a0 Instead of the drop down box going blank since the input don't match the drop down box, the drop down box remains a00092. If i keep typing past a0 with more values like a02 it will make the drop down box blank, but if i stop at a0 it will leave the drop down box with a value.
I was wondering if there was a way to make sure that if i have a0 in the the field an i go an click off of it or click on another field or someway to make it where that once i continue to fill out the form that the drop down box will not continue to say a00092 an will instead go blank.

Here is the html

Expand|Select|Wrap|Line Numbers
  1. Customer Number*:<input type="text" name="custnum" id="clientID" value=""  ONkeyup="autoComplete(this,this.form.customer,'value',false)"/>
  2. <SELECT NAME="customer" id="options"
  3. onChange="this.form.custnum.value=this.options[this.selectedIndex].value;">
  4. <option value="" selected></option>
  5. <cfoutput query="getcustnum">
  6. <option value="#fk_custNum#">#fk_custNum#</option>
  7. </cfoutput>
  8. </SELECT>


javascript that appears on html page.

Expand|Select|Wrap|Line Numbers
  1. <SCRIPT LANGUAGE="JavaScript" SRC="autocomplete.js"></SCRIPT>
  2.     <script type="text/javascript" src="autofill.js"></script>
  3. <script type="text/javascript">
  4.  
  5. var ajax = new sack();
  6.     var currentClientID=false;
  7.     function getClientData()
  8.     {
  9.         var clientId = document.getElementById('clientID').value;
  10.         var customer = document.getElementById('options').value;
  11.         if (clientId != "" && customer != "") {
  12.             currentClientID = clientId
  13.             ajax.requestFile = 'getClient.cfm?custnum='+clientId;    // Specifying which file to get
  14.             ajax.onCompletion = showClientData;    // Specify function that will be executed after file has been found
  15.             ajax.runAJAX();        // Execute AJAX function            
  16.     }}
  17.  
  18.  
  19.  
  20.  
  21.  
  22.     function showClientData()
  23.     {
  24.         var formObj = document.forms['page1'];
  25.         var resp = ajax.response.split(",");
  26.  
  27.       if (ajax.response == "") { // you may want to trim here just in case
  28.           formObj.cust_company.value = "";
  29.           formObj.fname.value = "";
  30.           formObj.lname.value = "";
  31.           formObj.add1.value = "";
  32.           formObj.city.value = "";
  33.           formObj.state.value = "";
  34.           formObj.zip.value = "";
  35.           formObj.email.value = "";
  36.           formObj.pri_phone.value = "";
  37.           formObj.sec_phone.value = "";
  38.           formObj.notes.value = "";
  39.  
  40.       } else {
  41.           var resp = ajax.response.split(",");
  42.           formObj.cust_company.value = resp[1];
  43.           formObj.fname.value = resp[2];
  44.           formObj.lname.value = resp[3];
  45.           formObj.add1.value = resp[4];
  46.           formObj.city.value = resp[5];
  47.           formObj.state.value = resp[6];
  48.           formObj.zip.value = resp[7];
  49.           formObj.email.value = resp[8];
  50.           formObj.pri_phone.value = resp[9];
  51.           formObj.sec_phone.value = resp[10];
  52.           formObj.notes.value = resp[11];
  53.       }
  54.     }
  55. </script>
autocomplete.js this autocomplets the form
Expand|Select|Wrap|Line Numbers
  1. function autoComplete (field, select, property, forcematch) {
  2.     var found = false;
  3.     for (var i = 0; i < select.options.length; i++) {
  4.     if (select.options[i][property].toUpperCase().indexOf(field.value.toUpperCase()) == 0) {
  5.         found=true; break;
  6.         }
  7.     }
  8.     if (found) { select.selectedIndex = i; }
  9.     else { select.selectedIndex = -1; }}


autofill.js this autofills the form

Expand|Select|Wrap|Line Numbers
  1. function sack(file) {
  2.     this.xmlhttp = null;
  3.  
  4.     this.resetData = function() {
  5.         this.method = "POST";
  6.           this.queryStringSeparator = "?";
  7.         this.argumentSeparator = "&";
  8.         this.URLString = "";
  9.         this.encodeURIString = true;
  10.           this.execute = false;
  11.           this.element = null;
  12.         this.elementObj = null;
  13.         this.requestFile = file;
  14.         this.vars = new Object();
  15.         this.responseStatus = new Array(2);
  16.       };
  17.  
  18.     this.resetFunctions = function() {
  19.           this.onLoading = function() { };
  20.           this.onLoaded = function() { };
  21.           this.onInteractive = function() { };
  22.           this.onCompletion = function() { };
  23.           this.onError = function() { };
  24.         this.onFail = function() { };
  25.     };
  26.  
  27.     this.reset = function() {
  28.         this.resetFunctions();
  29.         this.resetData();
  30.     };
  31.  
  32.     this.createAJAX = function() {
  33.         try {
  34.             this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  35.         } catch (e1) {
  36.             try {
  37.                 this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
  38.             } catch (e2) {
  39.                 this.xmlhttp = null;
  40.             }
  41.         }
  42.  
  43.         if (! this.xmlhttp) {
  44.             if (typeof XMLHttpRequest != "undefined") {
  45.                 this.xmlhttp = new XMLHttpRequest();
  46.             } else {
  47.                 this.failed = true;
  48.             }
  49.         }
  50.     };
  51.  
  52.     this.setVar = function(name, value){
  53.         this.vars[name] = Array(value, false);
  54.     };
  55.  
  56.     this.encVar = function(name, value, returnvars) {
  57.         if (true == returnvars) {
  58.             return Array(encodeURIComponent(name), encodeURIComponent(value));
  59.         } else {
  60.             this.vars[encodeURIComponent(name)] = Array(encodeURIComponent(value), true);
  61.         }
  62.     }
  63.  
  64.     this.processURLString = function(string, encode) {
  65.         encoded = encodeURIComponent(this.argumentSeparator);
  66.         regexp = new RegExp(this.argumentSeparator + "|" + encoded);
  67.         varArray = string.split(regexp);
  68.         for (i = 0; i < varArray.length; i++){
  69.             urlVars = varArray[i].split("=");
  70.             if (true == encode){
  71.                 this.encVar(urlVars[0], urlVars[1]);
  72.             } else {
  73.                 this.setVar(urlVars[0], urlVars[1]);
  74.             }
  75.         }
  76.     }
  77.  
  78.     this.createURLString = function(urlstring) {
  79.         if (this.encodeURIString && this.URLString.length) {
  80.             this.processURLString(this.URLString, true);
  81.         }
  82.  
  83.         if (urlstring) {
  84.             if (this.URLString.length) {
  85.                 this.URLString += this.argumentSeparator + urlstring;
  86.             } else {
  87.                 this.URLString = urlstring;
  88.             }
  89.         }
  90.  
  91.         // prevents caching of URLString
  92.         this.setVar("rndval", new Date().getTime());
  93.  
  94.         urlstringtemp = new Array();
  95.         for (key in this.vars) {
  96.             if (false == this.vars[key][1] && true == this.encodeURIString) {
  97.                 encoded = this.encVar(key, this.vars[key][0], true);
  98.                 delete this.vars[key];
  99.                 this.vars[encoded[0]] = Array(encoded[1], true);
  100.                 key = encoded[0];
  101.             }
  102.  
  103.             urlstringtemp[urlstringtemp.length] = key + "=" + this.vars[key][0];
  104.         }
  105.         if (urlstring){
  106.             this.URLString += this.argumentSeparator + urlstringtemp.join(this.argumentSeparator);
  107.         } else {
  108.             this.URLString += urlstringtemp.join(this.argumentSeparator);
  109.         }
  110.     }
  111.  
  112.     this.runResponse = function() {
  113.         eval(this.response);
  114.     }
  115.  
  116.     this.runAJAX = function(urlstring) {
  117.         if (this.failed) {
  118.             this.onFail();
  119.         } else {
  120.             this.createURLString(urlstring);
  121.             if (this.element) {
  122.                 this.elementObj = document.getElementById(this.element);
  123.             }
  124.             if (this.xmlhttp) {
  125.                 var self = this;
  126.                 if (this.method == "GET") {
  127.                     totalurlstring = this.requestFile + this.queryStringSeparator + this.URLString;
  128.                     this.xmlhttp.open(this.method, totalurlstring, true);
  129.                 } else {
  130.                     this.xmlhttp.open(this.method, this.requestFile, true);
  131.                     try {
  132.                         this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
  133.                     } catch (e) { }
  134.                 }
  135.  
  136.                 this.xmlhttp.onreadystatechange = function() {
  137.                     switch (self.xmlhttp.readyState) {
  138.                         case 1:
  139.                             self.onLoading();
  140.                             break;
  141.                         case 2:
  142.                             self.onLoaded();
  143.                             break;
  144.  
  145.                         case 3:
  146.                             self.onInteractive();
  147.                             break;
  148.                         case 4:
  149.                             self.response = self.xmlhttp.responseText;
  150.                             self.responseXML = self.xmlhttp.responseXML;
  151.                             self.responseStatus[0] = self.xmlhttp.status;
  152.                             self.responseStatus[1] = self.xmlhttp.statusText;
  153.  
  154.                             if (self.execute) {
  155.                                 self.runResponse();
  156.                             }
  157.  
  158.                             if (self.elementObj) {
  159.                                 elemNodeName = self.elementObj.nodeName;
  160.                                 elemNodeName.toLowerCase();
  161.                                 if (elemNodeName == "input"
  162.                                 || elemNodeName == "select"
  163.                                 || elemNodeName == "option"
  164.                                 || elemNodeName == "textarea") {
  165.                                     self.elementObj.value = self.response;
  166.                                 } else {
  167.                                     self.elementObj.innerHTML = self.response;
  168.                                 }
  169.                             }
  170.                             if (self.responseStatus[0] == "200") {
  171.                                 self.onCompletion();
  172.                             } else {
  173.                                 self.onError();
  174.                             }
  175.  
  176.                             self.URLString = "";
  177.                             break;
  178.                     }
  179.                 };
  180.  
  181.                 this.xmlhttp.send(this.URLString);
  182.             }
  183.         }
  184.     };
  185.  
  186.     this.reset();
  187.     this.createAJAX();
  188. }
  189.  
Thank you in advance,
Rach
Oct 8 '08 #1
Share this Question
Share on Google+
10 Replies


rnd me
Expert 100+
P: 427
the earlier an autocomplete suggests something, the more useful it is.

with a00092, a0 does indeed match something, perhaps more than one.

when would you want to clear it?
possibiblities include when the input is cleared, upon hitting backspace, etc.

if all the numbers are the same length, you could not fire the routine until the input's value is long enough, but would that still be helpful?

it should be easy enough to do, i just don't know where/when to do it.
Oct 8 '08 #2

100+
P: 769
Hey rnd me,

Thank you for your response. Well the main issue i am having is that basically like in my example if the user who is typing in the input field leaves it a0 then it will leave the drop down box a00092. The only way to get rid of the drop down box value is by continuing to type till the input field don't match the drop down box. I also figured out if you put a space after the a0 that it will go away. I was thinking that once the user clicks in the first name field that it would make the drop down box empty if the values for input and drop down box don't match, its the only way i can think to do it.

The only concern i have is i am afraid the user will try to go to the drop down box an try to select a empty field in fear that if they leave it saying a00092 that it will put whats in a00092 instead of what there currently typing it. But i also have some who know how to use a computer an will just go straight to first name an leave the drop down box alone. Is there away to make it where the user goes away from input that it will make drop down blank an when the user goes to type in first name?

Thank you,
Rach
Oct 8 '08 #3

rnd me
Expert 100+
P: 427
after quite a bit of thinking about it, and reviewing the code, it seems that the behavior is actually correct in it's current shape.

clearing the selection in the drop-down removes some of its utility.
you are currently hitting partial matches, which i think is to be expected.

i have struggled with a related problem myself.
eventually i figured out that the best thing to do was to re-label my controls.
i made it obvious with words, colors, and font size that the drop down was a "ez preset". make it look smaller and less important. make sure to use the word preset, so people won't think that it is the important control. i also set the select's tabindex="-1" to prevent keyboard control, again to de-emphasize its importance.

also you can make it apperent that the text input is required, and perhaps validate it before allowing the user to move on.


let me know if this makes any sense.
Oct 8 '08 #4

100+
P: 769
Hey rnd me,

You do make perfect since. An i wish it was as easy as changing font, size an color to make them understand that the drop down box is not nearly as important. However, i don't got the smartest tools in the shed. For one project to try to get people to understand we made the font size 30, bold and red and they still didn't understand that! With the text input i do have it validate now before they submit. The problem i am having is that basically although the input box an drop down box don't match the drop down box still has its value. An i know that they will try to change the drop down box to blank. An there wont be a blank value in there an then all get calls. Also eventually if i did have a blank value in there for them to choose they would eventually complain about having to choose the blank value an say well it should go blank automatically for me.Is there anyway to make the drop down box go blank once they click on another field or do something? i am afraid leaving it the way it is would confuse the users.

an i am also noticing another problem. If i type in the customer number a0009 an go an select the drop down box which is showing a00092 . It wont make the input box change from a0009 to a00092 (if i go to select a00092 from the drop down box). If i just go straight to the drop down box (an don't type anything into input) an select a00092 it will fill in the input field just fine.Is there anyway to make it where i select the value from the drop down box that it will overwrite the value that is in the input field?

Thank you,
Rach
Oct 9 '08 #5

rnd me
Expert 100+
P: 427
sounds frustrating, programming would be a lot easier without pesky users getting in the way, i feel your pain.

Hey rnd me,

.Is there anyway to make the drop down box go blank once they click on another field or do something? i am afraid leaving it the way it is would confuse the users.
you can use the onfocus event of the name input to verify a match between combo and input:
i don't see the code for that particular input, but here's what you need to add to the tag:

onfocus="var userVal = this.form.custnum.value; var dropVal =this.form.options.options[this.form.options.selectedIndex].value; if( userVal != dropVal ){ alert('please enter a valid customer number'); this.form.custnum.focus(); }"

whew! i think that should work, though i didn't test it.
what it does?

grabs the cust number input's value, and the drop down value. if they aren't the same, complain and return focus to the cust number input.




Is there anyway to make it where i select the value from the drop down box that it will overwrite the value that is in the input field?
it will only replace it when the selected option changes from one value to another.
you could manually fire it by adding to the select tag: onclick="this.onchange();".
this is force the update every time the select if used.





hope this helps you out.
Oct 9 '08 #6

100+
P: 769
sounds frustrating, programming would be a lot easier without pesky users getting in the way, i feel your pain.


you can use the onfocus event of the name input to verify a match between combo and input:
i don't see the code for that particular input, but here's what you need to add to the tag:

onfocus="var userVal = this.form.custnum.value; var dropVal =this.form.options.options[this.form.options.selectedIndex].value; if( userVal != dropVal ){ alert('please enter a valid customer number'); this.form.custnum.focus(); }"

whew! i think that should work, though i didn't test it.
what it does?

grabs the cust number input's value, and the drop down value. if they aren't the same, complain and return focus to the cust number input.






it will only replace it when the selected option changes from one value to another.
you could manually fire it by adding to the select tag: onclick="this.onchange();".
this is force the update every time the select if used.





hope this helps you out.
Hey rnd me,

Its very frustrating. Especially since there in there 20's! I mean i could understand someone in there 30's or 40's having trouble with a form. But someone in there 20's seems wrong. But anyway i ended up applying the onfocus to my insert contact button. I realized that if i make them match an go to company name all run into problems because users can add new customer numbers that don't already exist. An the onclick works wonderful :).

I know we discussed this but is there a way to make the drop down field go blank if the drop down box don't match the input field?it just seems really weird to look at the customer number (input field) saying a0009 and the drop down box saying a00092 or what would you recommend saying to them so they wouldn't get confused? Basically the customer number an drop down field have to match to add a user that already exists but if a user don't exist then don't have to match since don't have to insert. Not sure how to say that without being wordy which is why wanted to just make drop down field go blank. I am just afraid there get confused .

Thank you for all the help :),
Rach
Oct 9 '08 #7

rnd me
Expert 100+
P: 427
I know we discussed this but is there a way to make the drop down field go blank if the drop down box don't match the input field?
Thank you for all the help :),
Rach

sure. forgot about that part.

revision of code i posted last time:

Expand|Select|Wrap|Line Numbers
  1. onfocus="var userVal = this.form.custnum.value; var dropVal =this.form.options.options[this.form.options.selectedIndex].value; if( userVal != dropVal ){ this.form.options.selectedIndex=0; alert('please enter a valid customer number'); this.form.custnum.focus(); }"

i added "this.form.options.selectedIndex=0" to reset the combo before the complaint box comes up. this assumes the first choice is blank, as thats what seems to be the case from the code you posted. you could use -1 instead of zero to really clear it out. i know -1 works in firefox, not sure about ie.

you could probably remove the alert if it's annoying. it would then just pop users back to customer number if invalid.
Oct 9 '08 #8

100+
P: 769
Hey rnd me,

That works perfectly! Thank you for all the help!!!!

Rach
Oct 9 '08 #9

rnd me
Expert 100+
P: 427
hey no prob.

forms are like othello: a minute to learn and a lifetime to master.
i bet they cause more headache than any other aspect of web dev.
my favorite form trick is seeing all the fields blank when i hit back. that's fun.

anyways, glad to hear everything is working.

ya'll come back now, ya hear?
Oct 9 '08 #10

100+
P: 769
Hey rnd me,

Yes that is so true! I was going to say that shopping carts probably cause more headaches, but shopping carts are made up of forms so yes you are right :). But thank you again for all your help an trust me all be back :).

Thank you again,
Rach
Oct 10 '08 #11

Post your reply

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