typeahead.js的样例文档很不详细,必须查API,而API也写得比较简略。
我这里给一个比较典型的样例,供参考。
典型用况:修改一条person记录。服务端要你上传personId参数, 但用户只记得personName; 这时你要让用户在一个输入框里输入personName, 搜索出person信息,用户选中一个记录,系统再在另一个只读的输入框里记录被选中的personId, 最后提交表单上传到服务端。
表单DOM:
<form> <table> <tr> <td>Person Name</td> <td><input type="text" class="typeahead" name="personName" id="personNameInput" placeholder="输入Person Name搜索"/> </td> </tr> <tr> <td>Person ID</td> <td><input type="text" name="personId" id="personIdInput" readonly/> </td> </tr> ... </table> </form>
其实也可以只提供一个输入框:用户输入Person Name并选择后,系统在输入框中显示Person ID. 但Person Name和Person ID一个是字符串类型,一个是数字类型。 遇到这种情况,typeahead.js会有个bug: 第一次搜索正常,清空输入框再次搜索就会报JS语法错误。
typeahead相关javascript:
var persons = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('personName'), //服务端返回的json中, Person Name对应的字段叫personName queryTokenizer: Bloodhound.tokenizers.whitespace, remote:{ url: '/personService?personName=%QUERY', //'%QUERY' 将被用户输入的值代替 filter: function(resp){ //服务端未必直接以json array方式返回搜索结果。如果不是的话,指定一下搜索结果在json中的路径。 return resp.personList; } } }); persons.initialize(); $('#personNameInput').typeahead({ //把这个输入框变成auto complete风格 hint: true, highlight: true, minLength: 1 }, { name: 'thePersons', //其实没什么用,只是用来构建生成的dom元素的css class名 displayKey: 'personName', //选择好结果后,输入框里显示的字段 source: persons.ttAdapter(), //请照抄 templates: { //这个函数决定下拉列表中的每一行怎么渲染。 suggestion: Handlebars.compile('<p>ID:{{personId}} - name:{{personName}}</p>') //这是个模板,里面的{{xxx}}中的xxx是服务端所返回JSON数据中所对应的字段。下文会说明Handlebars的角色. } }).on('typeahead:selected',function(evt,datum){ $('#personIdInput').val(datum.personId); //用户从下拉中选择某项后,刷新那个只读的personId值 });
还要引入这些JS:
<script src="/js/jquery-1.10.2.min.js"></script> <!--handlebars是typeahead所使用的模板引擎,似乎还不能换成别的 --> <script src="/js/handlebars-v2.0.0.js"></script> <script src="/js/typeahead.bundle.min.js"></script>
还有一个很挫的地方:typeahead没有直接提供一个好看的css, 如果你不引入任何css, 所生成的下拉列表就会很丑很丑。 我的前端样式框架是twitter bootstrap, 网上搜了下,下面这个还不错:
https://github.com/bassjobsen/typeahead.js-bootstrap-css