Solved

Javascript autocomplete

Posted on 2013-10-29
15
666 Views
Last Modified: 2013-10-30
I am working on a form that is web based and I need to include a look-up for common medications so the field auto completes.
So if someone started typing Tyl.... it would show an auto complete for Tylenol (below the field) so the user can click the word instead of typing it. Because spelling Acetaminophen  on a touch screen can take a long time and be misspelled. My target is an input id on a form and from the looks of it my only avenue is JavaScript for this. It would also be good if I could use an external file like, medicines.txt to maintain a list so I don't have them hard-coded into the form.
0
Comment
Question by:rodneygray
  • 7
  • 5
  • 2
  • +1
15 Comments
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 39608668
For the autocomplete, jQuery have a really nice implementation:
http://jqueryui.com/autocomplete/

Of course this might be a bit overkill if you're not using jquery ui.
Implementing it from scratch in javascrip is not that difficult either.
Also have a look at this: http://complete-ly.appspot.com/

For the data it all depends on the amount of data we're talking about.
You can either put everything in a separate js file that will be cached by most browsers but might take a while to load the first time or simply use ajax to get the data based on the user input.
0
 
LVL 1

Expert Comment

by:BStrignano
ID: 39608682
Two options, do an AJAX query back to the server with the search on the text box, personally i would recommend jQuery to facilitate this. Or you can load the list as json into a hidden text area on the form when it loads, move it into an object, and iterate over it on the onchanged event of the text box. Short circuit the javascript function not to do the lookup unless the user has typed at least three characters.
Then create (un-hide) a div beneath the box containing a list box to display the results and capture the selected value when the user clicks an item.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 500 total points
ID: 39608793
jQuery Autocomplete is a pretty good solution.  Try this with "A", "E", and "F" to see the behavior.
http://www.laprbass.com/RAY_jquery_autocomplete.php

<?php // RAY_jquery_autocomplete.php
error_reporting(E_ALL);

// IF WE GOT THE SUBMITTED DATA
$q = !empty($_GET['q']) ? $_GET['q'] : NULL;
if ($q) echo "YOU CHOSE $q";
?>
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />

<title>jQuery UI Autocomplete Demonstration</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="http://jqueryui.com/autocomplete/resources/demos/style.css" />

<script>
$(function() {
  var availableFoods = [
    "Apple"
  , "Banana"
  , "Carrot"
  , "Date"
  , "Eggplant"
  , "Fries"
  , "Garlic"
  ];
  $( "#foods" ).autocomplete({
    source: availableFoods
  });
});
</script>
</head>

<body>
<form>
<div class="ui-widget">
  <label for="tags">Foods: </label>
  <input name="q" id="foods" />
</div>
<input type="submit" />
</form>
</body>
</html>

Open in new window

0
 
LVL 30

Expert Comment

by:Alexandre Simões
ID: 39609092
@BStrignano: "Or you can load the list as json into a hidden text area on the form when it loads"
This is not a good practice.
If the data is static (like it appears here) you should put it in a separate *.js file.
This will let the browsers cache the file like any other static resource file and also, as it's already a js file the data inside should be already in the JSON form, avoiding parsing tasks.
Ex: var data = [ { }, { }, { }, ... ]

For me, if the source data doesn't really change data much, this is the best option for performance.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39609154
I would just be guessing about the list of drugs, but if the OP would show us a list of the drugs, we could suggest some ideas around the "medicines.txt" idea.  Probably suggestions would include a data base.  Some of this will depend on the other parts of the app.
0
 
LVL 1

Author Comment

by:rodneygray
ID: 39609554
I presently do not have the list of drugs that will be used I am using this as framework for other areas I will be auto completing also.
I'd like to do auto-completes on medical conditions and such as well.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39609658
Here is a strategy that you could probably extend.  See line 57 first, then look at lines 9-36

<?php // RAY_jquery_autocomplete.php
error_reporting(E_ALL);

// IF WE GOT THE SUBMITTED DATA
$q = !empty($_GET['q']) ? $_GET['q'] : NULL;
if ($q) echo "YOU CHOSE $q";

// THE OPTIONS COULD COME FROM A FILE OR DATA BASE QUERY
$options = <<<EOD
    "Apple"
  , "Banana"
  , "Carrot"
  , "Date"
  , "Eggplant"
  , "Fries"
  , "Garlic"
  , "Hummus"
  , "Ice cream"
  , "Jelly"
  , "Kumquat"
  , "Liver"
  , "Mango"
  , "Nectarine"
  , "Orange"
  , "Peach"
  , "Quiche"
  , "Rice"
  , "Salami"
  , "Tomato"
  , "Ugli fruit"
  , "Vanilla"
  , "Watercress"
  , "Xanthan gum"
  , "Yam"
  , "Zucchini"
EOD;

// CREATE THE HTML DOCUMENT USING HEREDOC NOTATION TO INJECT THE OPTIONS INTO THE JAVASCRIPT
$html = <<<ENDHTML
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />

<title>jQuery UI Autocomplete Demonstration</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="http://jqueryui.com/autocomplete/resources/demos/style.css" />

<script>
$(function() {
  var availableFoods = [
  $options
  ];
  $( "#foods" ).autocomplete({
    source: availableFoods
  });
});
</script>
</head>

<body>
<form>
<div class="ui-widget">
  <label for="tags">Foods: </label>
  <input name="q" id="foods" />
</div>
<input type="submit" />
</form>
</body>
</html>
ENDHTML;

echo $html;

Open in new window

HTH, ~Ray
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 1

Author Comment

by:rodneygray
ID: 39609747
I have tried implementing your solution Ray but am having an issue.
Test Page

$(function() {
  var quickZip = [
    "31533"
  , "31534"
  , "31535"
  , "31510"
  , "31519"
  ];
  $( "#javatbd797485X9X110zip" ).autocomplete({
    source: quickZip
  });
});

/*
 ****** Quick City lookup ******
*/
$(function() {
  var quickCity = [
    "Alma"
  , "Broxton"
  , "Douglas"
  , "Pearson"
  , "Tifton"
  ];
  $( "#javatbd797485X9X110city" ).autocomplete({
    source: quickCity
  });
});

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39609806
Uhh, no thanks.  Please just post the script here in the code snippet.
Untrusted Connection?
0
 
LVL 1

Author Comment

by:rodneygray
ID: 39609846
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39609853
Here is the source code. What should we be looking at?
<!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" xml:lang="en" lang="en">
	<head>
                                                                <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>Autocomplete test</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="http://jqueryui.com/autocomplete/resources/demos/style.css" />

<meta name="generator" content="LimeSurvey http://www.limesurvey.org" />

<!-- The following line includes jquery-ui.css or jquery-ui-custom.css from template dir, template.css and needed specific css file for survey -->
<link rel='stylesheet' type='text/css' media='all' href='/upload/templates/Original_default/jquery-ui-custom.css' />
<link rel='stylesheet' type='text/css' media='all' href='/upload/templates/Original_default/template.css' />


<!--[if lte IE 6]>
<link rel="stylesheet" type="text/css" href="/upload/templates/Original_default/ie_fix_6.css" />
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="/upload/templates/Original_default/ie_fix_7.css" />
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="/upload/templates/Original_default/ie_fix_8.css" />
<![endif]-->

<!-- The following CSS hides visual elements of the progress bar from screen readers. -->
<style type="text/css" media="aural tty">
    progress-graph .zero, progress-graph .graph, progress-graph .cent { display: none; }
		</style>
	<!-- The following line includes jquery.js, jquery-ui.js, survey_runtime.js , template.js and needed specific js file for survey -->
	<script type='text/javascript' src='/scripts/jquery/jquery.js'></script>
<script type='text/javascript' src='/scripts/jquery/jquery-ui.js'></script>
<script type='text/javascript' src='/scripts/jquery/jquery.ui.touch-punch.min.js'></script>
<script type='text/javascript' src='/scripts/survey_runtime.js'></script>
<script type='text/javascript' src='/upload/templates/Original_default/template.js'></script>

<link rel="shortcut icon" href="/upload/templates/Original_default/favicon.ico" />

</head>
<body class="default lang-en groupbygroup showprogress showqnumcode-X">
    <div class="outerframe">
        <table class="innerframe">
            <tr>
                <td>
                                                <form id="limesurvey" name="limesurvey" autocomplete="off" action="/index.php/survey/index" method="post">

<!-- START THE SURVEY -->
<table class="welcome-table">
    <tr>
        <td class="survey-description">
            <noscript><span class='warningjs'>Caution: JavaScript execution is disabled in your browser. You may not be able to answer all questions in this survey. Please, verify your browser parameters.</span></noscript>
            <h1>Autocomplete test</h1><br />
            <p class='surveydescription'></p>
        </td>
    </tr>
    <tr>
        <td class="language-changer">
            
        </td>
    </tr>
    <tr>
        <td class="survey-welcome">
            <span class='surveywelcome'></span><br />
            <span class="x-questions">There is 1 question in this survey</span>
        </td>
    </tr>
</table>

<table class="navigator-table">
    <tr>
        <td class="save-all">
            			<input type='button' name='loadall' value='Load unfinished survey' class='saveall' onclick="javascript:addHiddenField(document.getElementById('limesurvey'),'loadall',this.value);document.getElementById('limesurvey').submit();" />
        </td>
        <td class="submit-buttons">
            <input type="hidden" name="move" value="movenext" id="movenext" />	<button class='submit' type='submit' accesskey='n' onclick="javascript:document.limesurvey.move.value = 'movenext';"
        value='Next' name='move2' id='movenextbtn' >Next</button>

        </td>
        <td class="clear-all">
            <input type='button' name='clearallbtn' value='Exit and clear survey' class='clearall' onclick="if (confirm('Are you sure you want to clear all your responses?')) {
window.open('/index.php/797485/move/clearall/lang/en', '_self')}" />
        </td>
    </tr>
</table>
<input type='hidden' name='sid' value='797485' id='sid' />

<input type='hidden' name='lastgroupname' value='_WELCOME_SCREEN_' id='lastgroupname' />
<input type='hidden' name='LEMpostKey' value='512271979' id='LEMpostKey' />
<input type='hidden' name='thisstep' id='thisstep' value='0' />

</form>
    		</td>
    	</tr>
    </table>
</div><script type="text/javascript" src="/scripts/expressions/em_javascript.js"></script>
<script type='text/javascript'>
<!--
var LEMmode='group';
var LEMgseq=-1;
function ExprMgr_process_relevance_and_tailoring(evt_type,sgqa,type){
if (typeof LEM_initialized == 'undefined') {
LEM_initialized=true;
LEMsetTabIndexes();
}
if (evt_type == 'onchange' && (typeof last_sgqa !== 'undefined' && sgqa==last_sgqa) && (typeof last_evt_type !== 'undefined' && last_evt_type == 'TAB' && type != 'checkbox')) {
  last_evt_type='onchange';
  last_sgqa=sgqa;
  return;
}
last_evt_type = evt_type;
last_sgqa=sgqa;

}
//-->
</script>


	</body>
</html>

Open in new window

0
 
LVL 1

Author Comment

by:rodneygray
ID: 39609875
Line 38 is where the modified code is for the words, line 7-10 are from the test example you gave me.
The next page is where the action should be happening.
For some reason it does not appear to be firing the JS and drop down.
I've tried multiple variations of it.

image of autocomplete field
template.js
                                                                                                                                /*
 * LimeSurvey
 * Copyright (C) 2007 The LimeSurvey Project Team / Carsten Schmitz
 * All rights reserved.
 * License: GNU/GPL License v2 or later, see LICENSE.php
 * LimeSurvey is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See COPYRIGHT.php for copyright notices and details.
 * 
 * 
 * Description: Javascript file for templates. Put JS-functions for your template here.
 * 
 * 
 * $Id:$
 *
 ****** Quick Zip lookup ******
 */
$(function() {
  var quickZip = [
    "31533"
  , "31534"
  , "31535"
  , "31510"
  , "31519"
  ];
  $( "#javatbd797485X9X110zip" ).autocomplete({
    source: quickZip
  });
});

/*
 ****** Quick City lookup ******
*/
$(function() {
  var quickCity = [
    "Alma"
  , "Broxton"
  , "Douglas"
  , "Pearson"
  , "Tifton"
  ];
  $( "#javatbd797485X9X110city" ).autocomplete({
    source: quickCity
  });
});
/*
 * The function focusFirst puts the Focus on the first non-hidden element in the Survey. 
 * 
 * Normally this is the first input field (the first answer).
 */
function focusFirst(Event)
{
	
	$('#limesurvey :input:visible:enabled:first').focus();

}
/*
 * The focusFirst function is added to the eventlistener, when the page is loaded.
 * 
 * This can be used to start other functions on pageload as well. Just put it inside the 'ready' function block
 */

/* Uncomment below if you want to use the focusFirst function */
/*
$(document).ready(function(){
	focusFirst();
});
*/



function correctPNG() // correctly handle PNG transparency in Win IE 5.5 & 6.
{
   var arVersion = navigator.appVersion.split("MSIE")
   var version = parseFloat(arVersion[1])
   if ((version >= 5.5) && (version<7) && (document.body.filters)) 
   {
      for(var i=0; i<document.images.length; i++)
      {
         var img = document.images[i]
         var imgName = img.src.toUpperCase()
         if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
         {
            var imgID = (img.id) ? "id='" + img.id + "' " : "";
            var imgClass = (img.className) ? "class='" + img.className + "' " : "";
            var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
            var imgStyle = "display:inline-block;" + img.style.cssText;
            if (img.align == "left") imgStyle = "float:left;" + imgStyle;
            if (img.align == "right") imgStyle = "float:right;" + imgStyle;
            if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
            var strNewHTML = "<span " + imgID + imgClass + imgTitle
            + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
            + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
            + "(src='" + img.src + "', sizingMethod='scale');\"></span>" 
            img.outerHTML = strNewHTML
            i = i-1
         }
      }
   }    
}

$(document).ready(function(){

});
                                                                                                

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39609887
This seems to work OK.  Only tested on Chrome.

<?php // RAY_jquery_autocomplete.php
error_reporting(E_ALL);

// CREATE THE HTML DOCUMENT USING HEREDOC NOTATION TO INJECT THE OPTIONS INTO THE JAVASCRIPT
$html = <<<ENDHTML
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />

<title>jQuery UI Autocomplete Demonstration</title>

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>

<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="http://jqueryui.com/autocomplete/resources/demos/style.css" />

<script>
$(function() {
  var quickZip = [
    "31533"
  , "31534"
  , "31535"
  , "31510"
  , "31519"
  ];
  var quickCity = [
    "Alma"
  , "Broxton"
  , "Douglas"
  , "Pearson"
  , "Tifton"
  ];
  $( "#javatbd797485X9X110city" ).autocomplete({
    source: quickCity
  });
  $( "#javatbd797485X9X110zip" ).autocomplete({
    source: quickZip
  });
});
</script>
</head>

<body>
<form>
<div class="ui-widget">
  <label for="tags">City: </label>
  <input name="city" id="javatbd797485X9X110city" />
</div>
<div class="ui-widget">
  <label for="tags">ZIP: </label>
  <input name="zip" id="javatbd797485X9X110zip" />
</div>
<input type="submit" />
</form>
</body>
</html>
ENDHTML;

echo $html;

Open in new window

HTH, ~Ray
0
 
LVL 1

Author Closing Comment

by:rodneygray
ID: 39611608
This was just what  I needed to get started. It sent me down the path to find the solution I needed which ended up being partially built-in to the framework I was using.
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 39611795
Thanks for the point and thanks for using EE, ~Ray
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Building a website can seem like a daunting task to the uninitiated but it really only requires knowledge of two basic languages: HTML and CSS.
Boost your ability to deliver ambitious and competitive web apps by choosing the right JavaScript framework to best suit your project’s needs.
In this tutorial viewers will learn how to code links for mobile sites that, once clicked, send a call or text to a specified number. For a telephone link (once clicked, calls a number), begin with a normal "<a href=" link tag. For the href, specify…
The viewer will learn how to count occurrences of each item in an array.

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now