java - How to make autocomplete to accept multiple values? -
i using following tutorial implement auto-complete works, problem accepts 1 value, need amend in way accept multiple values, such austria, germany, (comma used delimiter)
alternatively, please let me know if know of other example same accept multiple values.
dummydb.java
package net.viralpatel.autocomplete; import java.util.arraylist; import java.util.list; import java.util.stringtokenizer; public class dummydb { private int totalcountries; private string data = "afghanistan, albania, zimbabwe"; private list<string> countries; public dummydb() { countries = new arraylist<string>(); stringtokenizer st = new stringtokenizer(data, ","); while(st.hasmoretokens()) { countries.add(st.nexttoken().trim()); } totalcountries = countries.size(); } public list<string> getdata(string query) { string country = null; query = query.tolowercase(); list<string> matched = new arraylist<string>(); for(int i=0; i<totalcountries; i++) { country = countries.get(i).tolowercase(); if(country.startswith(query)) { matched.add(countries.get(i)); } } return matched; } }
index.jsp
<!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <link rel="stylesheet" type="text/css" href="css/jquery.autocomplete.css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> <script src="js/jquery.autocomplete.js"></script> <style> input { font-size: 120%; } </style> </head> <body> <h3>country</h3> <input type="text" id="country" name="country"/> <script> $("#country").autocomplete("getdata.jsp"); </script> </body> </html>
getdata.jsp
<%@page import="java.util.iterator"%> <%@page import="java.util.list"%> <%@page import="net.viralpatel.autocomplete.dummydb"%> <% dummydb db = new dummydb(); string query = request.getparameter("q"); list<string> countries = db.getdata(query); iterator<string> iterator = countries.iterator(); while(iterator.hasnext()) { string country = (string)iterator.next(); out.println(country); } %>
jquery.autocomplete.js
jquery.autocomplete = function(input, options) { // create link self var me = this; // create jquery object input element var $input = $(input).attr("autocomplete", "off"); // apply inputclass if necessary if (options.inputclass) $input.addclass(options.inputclass); // create results var results = document.createelement("div"); // create jquery object results var $results = $(results); $results.hide().addclass(options.resultsclass).css("position", "absolute"); if( options.width > 0 ) $results.css("width", options.width); // add body element $("body").append(results); input.autocompleter = me; var timeout = null; var prev = ""; var active = -1; var cache = {}; var keyb = false; var hasfocus = false; var lastkeypresscode = null; // flush cache function flushcache(){ cache = {}; cache.data = {}; cache.length = 0; }; // flush cache flushcache(); // if there data array supplied if( options.data != null ){ var sfirstchar = "", stmatchsets = {}, row = []; // no url specified, need adjust cache length make sure fits local data store if( typeof options.url != "string" ) options.cachelength = 1; // loop through array , create lookup structure for( var i=0; < options.data.length; i++ ){ // if row string, make array otherwise reference array row = ((typeof options.data[i] == "string") ? [options.data[i]] : options.data[i]); // if length zero, don't add list if( row[0].length > 0 ){ // first character sfirstchar = row[0].substring(0, 1).tolowercase(); // if no lookup array character exists, if( !stmatchsets[sfirstchar] ) stmatchsets[sfirstchar] = []; // if match string stmatchsets[sfirstchar].push(row); } } // add data items cache for( var k in stmatchsets ){ // increase cache size options.cachelength++; // add cache addtocache(k, stmatchsets[k]); } } $input .keydown(function(e) { // track last key pressed lastkeypresscode = e.keycode; switch(e.keycode) { case 38: // e.preventdefault(); moveselect(-1); break; case 40: // down e.preventdefault(); moveselect(1); break; case 9: // tab case 13: // return if( selectcurrent() ){ // make sure blur off current field $input.get(0).blur(); e.preventdefault(); } break; default: active = -1; if (timeout) cleartimeout(timeout); timeout = settimeout(function(){onchange();}, options.delay); break; } }) .focus(function(){ // track whether field has focus, shouldn't process results if field no longer has focus hasfocus = true; }) .blur(function() { // track whether field has focus hasfocus = false; hideresults(); }); hideresultsnow(); function onchange() { // ignore if following keys pressed: [del] [shift] [capslock] if( lastkeypresscode == 46 || (lastkeypresscode > 8 && lastkeypresscode < 32) ) return $results.hide(); var v = $input.val(); if (v == prev) return; prev = v; if (v.length >= options.minchars) { $input.addclass(options.loadingclass); requestdata(v); } else { $input.removeclass(options.loadingclass); $results.hide(); } }; function moveselect(step) { var lis = $("li", results); if (!lis) return; active += step; if (active < 0) { active = 0; } else if (active >= lis.size()) { active = lis.size() - 1; } lis.removeclass("ac_over"); $(lis[active]).addclass("ac_over"); // weird behaviour in ie // if (lis[active] && lis[active].scrollintoview) { // lis[active].scrollintoview(false); // } }; function selectcurrent() { var li = $("li.ac_over", results)[0]; if (!li) { var $li = $("li", results); if (options.selectonly) { if ($li.length == 1) li = $li[0]; } else if (options.selectfirst) { li = $li[0]; } } if (li) { selectitem(li); return true; } else { return false; } }; function selectitem(li) { if (!li) { li = document.createelement("li"); li.extra = []; li.selectvalue = ""; } var v = $.trim(li.selectvalue ? li.selectvalue : li.innerhtml); input.lastselected = v; prev = v; $results.html(""); $input.val(v); hideresultsnow(); if (options.onitemselect) settimeout(function() { options.onitemselect(li) }, 1); }; // selects portion of input string function createselection(start, end){ // reference input element var field = $input.get(0); if( field.createtextrange ){ var selrange = field.createtextrange(); selrange.collapse(true); selrange.movestart("character", start); selrange.moveend("character", end); selrange.select(); } else if( field.setselectionrange ){ field.setselectionrange(start, end); } else { if( field.selectionstart ){ field.selectionstart = start; field.selectionend = end; } } field.focus(); }; // fills in input box w/the first match (assumed best match) function autofill(svalue){ // if last user key pressed backspace, don't autofill if( lastkeypresscode != 8 ){ // fill in value (keep case user has typed) $input.val($input.val() + svalue.substring(prev.length)); // select portion of value not typed user (so next character erase) createselection(prev.length, svalue.length); } }; function showresults() { // position of input field right (in case dom shifted) var pos = findpos(input); // either use specified width, or autocalculate based on form element var iwidth = (options.width > 0) ? options.width : $input.width(); // reposition $results.css({ width: parseint(iwidth) + "px", top: (pos.y + input.offsetheight) + "px", left: pos.x + "px" }).show(); }; function hideresults() { if (timeout) cleartimeout(timeout); timeout = settimeout(hideresultsnow, 200); }; function hideresultsnow() { if (timeout) cleartimeout(timeout); $input.removeclass(options.loadingclass); if ($results.is(":visible")) { $results.hide(); } if (options.mustmatch) { var v = $input.val(); if (v != input.lastselected) { selectitem(null); } } }; function receivedata(q, data) { if (data) { $input.removeclass(options.loadingclass); results.innerhtml = ""; // if field no longer has focus or if there no matches, not display drop down if( !hasfocus || data.length == 0 ) return hideresultsnow(); if ($.browser.msie) { // put styled iframe behind calendar html select elements don't show through $results.append(document.createelement('iframe')); } results.appendchild(datatodom(data)); // autofill in complete box w/the first match long user hasn't entered in more data if( options.autofill && ($input.val().tolowercase() == q.tolowercase()) ) autofill(data[0][0]); showresults(); } else { hideresultsnow(); } }; function parsedata(data) { if (!data) return null; var parsed = []; var rows = data.split(options.lineseparator); (var i=0; < rows.length; i++) { var row = $.trim(rows[i]); if (row) { parsed[parsed.length] = row.split(options.cellseparator); } } return parsed; }; function datatodom(data) { var ul = document.createelement("ul"); var num = data.length; // limited results max number if( (options.maxitemstoshow > 0) && (options.maxitemstoshow < num) ) num = options.maxitemstoshow; (var i=0; < num; i++) { var row = data[i]; if (!row) continue; var li = document.createelement("li"); if (options.formatitem) { li.innerhtml = options.formatitem(row, i, num); li.selectvalue = row[0]; } else { li.innerhtml = row[0]; li.selectvalue = row[0]; } var = null; if (row.length > 1) { = []; (var j=1; j < row.length; j++) { extra[extra.length] = row[j]; } } li.extra = extra; ul.appendchild(li); $(li).hover( function() { $("li", ul).removeclass("ac_over"); $(this).addclass("ac_over"); active = $("li", ul).indexof($(this).get(0)); }, function() { $(this).removeclass("ac_over"); } ).click(function(e) { e.preventdefault(); e.stoppropagation(); selectitem(this) }); } return ul; }; function requestdata(q) { if (!options.matchcase) q = q.tolowercase(); var data = options.cachelength ? loadfromcache(q) : null; // recieve cached data if (data) { receivedata(q, data); // if ajax url has been supplied, try loading data } else if( (typeof options.url == "string") && (options.url.length > 0) ){ $.get(makeurl(q), function(data) { data = parsedata(data); addtocache(q, data); receivedata(q, data); }); // if there's been no data found, remove loading class } else { $input.removeclass(options.loadingclass); } }; function makeurl(q) { var url = options.url + "?q=" + encodeuri(q); (var in options.extraparams) { url += "&" + + "=" + encodeuri(options.extraparams[i]); } return url; }; function loadfromcache(q) { if (!q) return null; if (cache.data[q]) return cache.data[q]; if (options.matchsubset) { (var = q.length - 1; >= options.minchars; i--) { var qs = q.substr(0, i); var c = cache.data[qs]; if (c) { var csub = []; (var j = 0; j < c.length; j++) { var x = c[j]; var x0 = x[0]; if (matchsubset(x0, q)) { csub[csub.length] = x; } } return csub; } } } return null; }; function matchsubset(s, sub) { if (!options.matchcase) s = s.tolowercase(); var = s.indexof(sub); if (i == -1) return false; return == 0 || options.matchcontains; }; this.flushcache = function() { flushcache(); }; this.setextraparams = function(p) { options.extraparams = p; }; this.findvalue = function(){ var q = $input.val(); if (!options.matchcase) q = q.tolowercase(); var data = options.cachelength ? loadfromcache(q) : null; if (data) { findvaluecallback(q, data); } else if( (typeof options.url == "string") && (options.url.length > 0) ){ $.get(makeurl(q), function(data) { data = parsedata(data) addtocache(q, data); findvaluecallback(q, data); }); } else { // no matches findvaluecallback(q, null); } } function findvaluecallback(q, data){ if (data) $input.removeclass(options.loadingclass); var num = (data) ? data.length : 0; var li = null; (var i=0; < num; i++) { var row = data[i]; if( row[0].tolowercase() == q.tolowercase() ){ li = document.createelement("li"); if (options.formatitem) { li.innerhtml = options.formatitem(row, i, num); li.selectvalue = row[0]; } else { li.innerhtml = row[0]; li.selectvalue = row[0]; } var = null; if( row.length > 1 ){ = []; (var j=1; j < row.length; j++) { extra[extra.length] = row[j]; } } li.extra = extra; } } if( options.onfindvalue ) settimeout(function() { options.onfindvalue(li) }, 1); } function addtocache(q, data) { if (!data || !q || !options.cachelength) return; if (!cache.length || cache.length > options.cachelength) { flushcache(); cache.length++; } else if (!cache[q]) { cache.length++; } cache.data[q] = data; }; function findpos(obj) { var curleft = obj.offsetleft || 0; var curtop = obj.offsettop || 0; while (obj = obj.offsetparent) { curleft += obj.offsetleft curtop += obj.offsettop } return {x:curleft,y:curtop}; } } jquery.fn.autocomplete = function(url, options, data) { // make sure options exists options = options || {}; // set url option options.url = url; // set bulk local data options.data = ((typeof data == "object") && (data.constructor == array)) ? data : null; // set default values required options options.inputclass = options.inputclass || "ac_input"; options.resultsclass = options.resultsclass || "ac_results"; options.lineseparator = options.lineseparator || "\n"; options.cellseparator = options.cellseparator || "|"; options.minchars = options.minchars || 1; options.delay = options.delay || 400; options.matchcase = options.matchcase || 0; options.matchsubset = options.matchsubset || 1; options.matchcontains = options.matchcontains || 0; options.cachelength = options.cachelength || 1; options.mustmatch = options.mustmatch || 0; options.extraparams = options.extraparams || {}; options.loadingclass = options.loadingclass || "ac_loading"; options.selectfirst = options.selectfirst || false; options.selectonly = options.selectonly || false; options.maxitemstoshow = options.maxitemstoshow || -1; options.autofill = options.autofill || false; options.width = parseint(options.width, 10) || 0; this.each(function() { var input = this; new jquery.autocomplete(input, options); }); // don't break chain return this; } jquery.fn.autocompletearray = function(data, options) { return this.autocomplete(null, options, data); } jquery.fn.indexof = function(e){ for( var i=0; i<this.length; i++ ){ if( this[i] == e ) return i; } return -1; };
have @ this.
http://jqueryui.com/autocomplete/#multiple
also, mend autocomplete script once allowed multiple entries , mended allow values in list(similar jquery ui autocomplete combobox, can found @ same link mentioned above). script uses ';' delimiter ',' can occur in values in many cases. can find script @
also, let me tell good. have @ tokeninput
http://loopj.com/jquery-tokeninput/
it takes javascript array. leave me message if need more help.
Comments
Post a Comment