<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <Meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>flexselect tests</title> <link rel="stylesheet" href="flexselect.css" type="text/css" media="screen" /> <style> input { width: 400px; } label,input { display: block; } label { font-weight: bold; } input,.flexselect_dropdown li { font-size: 1em; } small { color: #999; } .flexselect_selected small { color: #ddd; } </style> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" type="text/javascript"></script> <script src="liquidMetal.js" type="text/javascript"></script> <script src="jquery.flexselect.js" type="text/javascript"></script> <script type="text/javascript"> $(document).ready(function() { $("select.special-flexselect").flexselect({ hideDropdownOnEmptyInput: true }); $("select.flexselect").flexselect(); $("input:text:enabled:first").focus(); $("form").submit(function() { alert($(this).serialize()); return false; }); }); </script> </head> <body> <form> <label>Pick a Top 100 University or College in north America: <em>(Start typing...)</em></label> <selectid="school" name="school" tabindex="1" data-placeholder="Start typing a school name..."> <option value=""></option> <option value="1">Massachusetts</option> <option value="2">Harvard University</option> <option value="3">University</Option> <option value="4">检验</option> <option value="5">测试</option>
</select>
<form> </body> </html>
jquery.flexselect.js
/**
* flexselect: a jQuery plugin,version: 0.5.2 (2013-01-21)
* @requires jQuery v1.3 or later
*
* FlexSelect is a jQuery plugin that makes it easy to convert a select Box into
* a Quicksilver-style,autocompleting,flex matching selection tool.
*
* For usage and examples,visit:
* http://rmm5t.github.com/jquery-flexselect/
*
* Licensed under the MIT:
* http://www.opensource.org/licenses/mit-license.PHP
*
* copyright (c) 2009-2012,Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
(function($) {
$.flexselect = function(select,options) { this.init(select,options); };
$.extend($.flexselect.prototype,{
settings: {
allowMismatch: false,allowMismatchBlank: true,// If "true" a user can backspace such that the value is nothing (even if no blank value was provided in the original criteria)
sortBy: 'score',// 'score' || 'name'
preSelection: true,hideDropdownOnEmptyInput: false,selectedClass: "flexselect_selected",dropdownClass: "flexselect_dropdown",inputIdTransform: function(id) { return id + "_flexselect"; },inputNameTransform: function(name) { return; },dropdownIdTransform: function(id) { return id + "_flexselect_dropdown"; }
},select: null,input: null,dropdown: null,dropdownList: null,cache: [],results: [],lastAbbreviation: null,abbreviationBeforeFocus: null,selectedindex: 0,picked: false,allowMouseMove: true,dropdownMouSEOver: false,// Workaround for poor IE behaviors
init: function(select,options) {
this.settings = $.extend({},this.settings,options);
this.select = $(select);
this.preloadCache();
this.renderControls();
this.wire();
},preloadCache: function() {
this.cache = this.select.children("option").map(function() {
return { name: $.trim($(this).text()),value: $(this).val(),score: 0.0 };
});
},renderControls: function() {
var selected = this.settings.preSelection ? this.select.children("option:selected") : null;
this.input = $("<input type='text' autocomplete='off' />").attr({
id: this.settings.inputIdTransform(this.select.attr("id")),name: this.settings.inputNameTransform(this.select.attr("name")),accesskey: this.select.attr("accesskey"),tabindex: this.select.attr("tabindex"),style: this.select.attr("style"),placeholder: this.select.attr("data-placeholder")
}).addClass(this.select.attr("class")).val($.trim(selected ? selected.text(): '')).css({
visibility: 'visible'
});
this.dropdown = $("<div></div>").attr({
id: this.settings.dropdownIdTransform(this.select.attr("id"))
}).addClass(this.settings.dropdownClass);
this.dropdownList = $("<ul></ul>");
this.dropdown.append(this.dropdownList);
this.select.after(this.input).hide();
$("body").append(this.dropdown);
},wire: function() {
var self = this;
this.input.click(function() {
self.lastAbbreviation = null;
self.focus();
});
this.input.mouseup(function(event) {
// This is so Safari selection actually occurs.
event.preventDefault();
});
this.input.focus(function() {
self.abbreviationBeforeFocus = self.input.val();
self.input.select();
if (!self.picked) self.filterResults();
});
this.input.blur(function() {
if (!self.dropdownMouSEOver) {
self.hide();
if (self.settings.allowMismatchBlank && $.trim($(this).val()) == '')
self.setValue('');
if (!self.settings.allowMismatch && !self.picked)
self.reset();
}
if (self.settings.hideDropdownOnEmptyInput)
self.dropdownList.show();
});
this.dropdownList.mouSEOver(function(event) {
if (!self.allowMouseMove) {
self.allowMouseMove = true;
return;
}
if (event.target.tagName == "LI") {
var rows = self.dropdown.find("li");
self.markSelected(rows.index($(event.target)));
}
});
this.dropdownList.mouseleave(function() {
self.markSelected(-1);
});
this.dropdownList.mouseup(function(event) {
self.pickSelected();
self.focusAndHide();
});
this.dropdown.mouSEOver(function(event) {
self.dropdownMouSEOver = true;
});
this.dropdown.mouseleave(function(event) {
self.dropdownMouSEOver = false;
});
this.dropdown.mousedown(function(event) {
event.preventDefault();
});
this.input.keyup(function(event) {
switch (event.keyCode) {
case 13: // return
event.preventDefault();
self.pickSelected();
self.focusAndHide();
break;
case 27: // esc
event.preventDefault();
self.reset();
self.focusAndHide();
break;
default:
self.filterResults();
break;
}
if (self.settings.hideDropdownOnEmptyInput){
if(self.input.val() == "")
self.dropdownList.hide();
else
self.dropdownList.show();
}
});
this.input.keydown(function(event) {
switch (event.keyCode) {
case 9: // tab
self.pickSelected();
self.hide();
break;
case 33: // pgup
event.preventDefault();
self.markFirst();
break;
case 34: // pgedown
event.preventDefault();
self.markLast();
break;
case 38: // up
event.preventDefault();
self.moveSelected(-1);
break;
case 40: // down
event.preventDefault();
self.moveSelected(1);
break;
case 13: // return
case 27: // esc
event.preventDefault();
event.stopPropagation();
break;
}
});
var input = this.input;
this.select.change(function () {
input.val($.trim($(this).children('option:selected').text()));
});
},filterResults: function() {
var abbreviation = this.input.val();
if (abbreviation == this.lastAbbreviation) return;
var results = [];
$.each(this.cache,function() {
this.score = LiquidMetal.score(this.name,abbreviation);
if (this.score > 0.0) results.push(this);
});
this.results = results;
if (this.settings.sortBy == 'score')
this.sortResultsByscore();
else if (this.settings.sortBy == 'name')
this.sortResultsByName();
this.renderDropdown();
this.markFirst();
this.lastAbbreviation = abbreviation;
this.picked = false;
this.allowMouseMove = false;
},sortResultsByscore: function() {
this.results.sort(function(a,b) { return b.score - a.score; });
},sortResultsByName: function() {
this.results.sort(function(a,b) { return a.name < b.name ? -1 : (a.name > b.name ? 1 : 0); });
},renderDropdown: function() {
var dropdownBorderWidth = this.dropdown.outerWidth() - this.dropdown.innerWidth();
var inputOffset = this.input.offset();
this.dropdown.css({
width: (this.input.outerWidth() - dropdownBorderWidth) + "px",top: (inputOffset.top + this.input.outerHeight()) + "px",left: inputOffset.left + "px",maxHeight: ''
});
var html = '';
$.each(this.results,function() {
//html += '<li>' + this.name + ' <small>[' + Math.round(this.score*100)/100 + ']</small></li>';
html += '<li>' + this.name + '</li>';
});
this.dropdownList.html(html);
this.adjustMaxHeight();
this.dropdown.show();
},adjustMaxHeight: function() {
var maxTop = $(window).height() + $(window).scrollTop() - this.dropdown.outerHeight();
var top = parseInt(this.dropdown.css('top'),10);
this.dropdown.css('max-height',top > maxTop ? (Math.max(0,maxTop - top + this.dropdown.innerHeight()) + 'px') : '');
},markSelected: function(n) {
if (n < 0 || n >= this.results.length) return;
var rows = this.dropdown.find("li");
rows.removeClass(this.settings.selectedClass);
this.selectedindex = n;
var row = $(rows[n]).addClass(this.settings.selectedClass);
var top = row.position().top;
var delta = top + row.outerHeight() - this.dropdown.height();
if (delta > 0) {
this.allowMouseMove = false;
this.dropdown.scrollTop(this.dropdown.scrollTop() + delta);
} else if (top < 0) {
this.allowMouseMove = false;
this.dropdown.scrollTop(Math.max(0,this.dropdown.scrollTop() + top));
}
},pickSelected: function() {
var selected = this.results[this.selectedindex];
if (selected) {
this.input.val(selected.name);
this.setValue(selected.value);
this.picked = true;
} else if (this.settings.allowMismatch) {
this.setValue.val("");
} else {
this.reset();
}
},setValue: function(val) {
if (this.select.val() === val) return;
this.select.val(val).change();
},hide: function() {
this.dropdown.hide();
this.lastAbbreviation = null;
},moveSelected: function(n) { this.markSelected(this.selectedindex+n); },markFirst: function() { this.markSelected(0); },markLast: function() { this.markSelected(this.results.length - 1); },reset: function() { this.input.val(this.abbreviationBeforeFocus); },focus: function() { this.input.focus(); },focusAndHide: function() { this.focus(); this.hide(); }
});
$.fn.flexselect = function(options) {
this.each(function() {
if (this.tagName == "SELECT") new $.flexselect(this,options);
});
return this;
};
})(jQuery);
liquidMetal.js
/**
* LiquidMetal,version: 1.2.1 (2012-04-21)
*
* A mimetic poly-alloy of Quicksilver's scoring algorithm,essentially
* LiquidMetal.
*
* For usage and examples,visit:
* http://github.com/rmm5t/liquidMetal
*
* Licensed under the MIT:
* http://www.opensource.org/licenses/mit-license.PHP
*
* copyright (c) 2009-2012,Ryan McGeary (ryan -[at]- mcgeary [*dot*] org)
*/
var LiquidMetal = (function() {
var score_NO_MATCH = 0.0;
var score_MATCH = 1.0;
var score_TRAILING = 0.8;
var score_TRAILING_BUT_STARTED = 0.9;
var score_BUFFER = 0.85;
var WORD_SEParaTORS = " \t_-";
return {
lastscore: null,lastscoreArray: null,score: function(string,abbrev) {
// short circuits
if (abbrev.length === 0) return score_TRAILING;
if (abbrev.length > string.length) return score_NO_MATCH;
// match & score all
var allscores = [];
var search = string.toLowerCase();
abbrev = abbrev.toLowerCase();
this._scoreAll(string,search,abbrev,-1,[],allscores);
// complete miss
if (allscores.length == 0) return 0;
// sum per-character scores into overall scores,// selecting the maximum score
var maxscore = 0.0,maxArray = [];
for (var i = 0; i < allscores.length; i++) {
var scores = allscores[i];
var scoreSum = 0.0;
for (var j = 0; j < string.length; j++) { scoreSum += scores[j]; }
if (scoreSum > maxscore) {
maxscore = scoreSum;
maxArray = scores;
}
}
// normalize max score by string length
// s. t. the perfect match score = 1
maxscore /= string.length;
// record maximum score & score array,return
this.lastscore = maxscore;
this.lastscoreArray = maxArray;
return maxscore;
},_scoreAll: function(string,searchIndex,abbrIndex,scores,allscores) {
// save completed match scores at end of search
if (abbrIndex == abbrev.length) {
// add trailing score for the remainder of the match
var started = (search.charat(0) == abbrev.charat(0));
var trailscore = started ? score_TRAILING_BUT_STARTED : score_TRAILING;
fillArray(scores,trailscore,scores.length,string.length);
// save score clone (since reference is persisted in scores)
allscores.push(scores.slice(0));
return;
}
// consume current char to match
var c = abbrev.charat(abbrIndex);
abbrIndex++;
// cancel match if a character is missing
var index = search.indexOf(c,searchIndex);
if (index == -1) return;
// match all instances of the abbreviaton char
var scoreIndex = searchIndex; // score section to update
while ((index = search.indexOf(c,searchIndex+1)) != -1) {
// score this match according to context
if (isNewWord(string,index)) {
scores[index-1] = 1;
fillArray(scores,score_BUFFER,scoreIndex+1,index-1);
}
else if (isUpperCase(string,index)) {
fillArray(scores,index);
}
else {
fillArray(scores,score_NO_MATCH,index);
}
scores[index] = score_MATCH;
// consume matched string and continue search
searchIndex = index;
this._scoreAll(string,allscores);
}
}
};
function isUpperCase(string,index) {
var c = string.charat(index);
return ("A" <= c && c <= "Z");
}
function isNewWord(string,index) {
var c = string.charat(index-1);
return (WORD_SEParaTORS.indexOf(c) != -1);
}
function fillArray(array,value,from,to) {
for (var i = from; i < to; i++) { array[i] = value; }
return array;
}
})();
List<Object> list = new ArrayList<Object>(); User user = new User(); user.setId(1); user.setUsername ("张三"); User user2 = new User(); user2.setId(2); user2.setUsername ("李四"); list.add(user); list.add(user2);