bootstrap3-typeahead文字自动补全插件

一、需求

项目中实现在类似百度搜索功能,在搜索框内输入文字,搜索框下方会出现自动匹配的内容列表,点击某一个,进行查询操作。

二、使用bootstrap3-typeahead自动补全插件实现

bootstrap3的js中没有集成此插件,需要单独引入bootstrap3-typeahead.js

/* =============================================================
 * bootstrap3-typeahead.js v4.0.2
 * https://github.com/bassjobsen/Bootstrap-3-Typeahead
 * =============================================================
 * Original written by @mdo and @fat
 * =============================================================
 * Copyright 2014 Bass Jobsen @bassjobsen
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============================================================ */


(function (root, factory) {

    'use strict';

    // CommonJS module is defined
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    }
    // AMD module is defined
    else if (typeof define === 'function' && define.amd) {
        define(['jquery'], function ($) {
            return factory($);
        });
    } else {
        factory(root.jQuery);
    }

}(this, function ($) {

    'use strict';
    // jshint laxcomma: true


    /* TYPEAHEAD PUBLIC CLASS DEFINITION
     * ================================= */

    var Typeahead = function (element, options) {
        this.$element = $(element);
        this.options = $.extend({}, Typeahead.defaults, options);
        this.matcher = this.options.matcher || this.matcher;
        this.sorter = this.options.sorter || this.sorter;
        this.select = this.options.select || this.select;
        this.autoSelect = typeof this.options.autoSelect == 'boolean' ? this.options.autoSelect : true;
        this.highlighter = this.options.highlighter || this.highlighter;
        this.render = this.options.render || this.render;
        this.updater = this.options.updater || this.updater;
        this.displayText = this.options.displayText || this.displayText;
        this.itemLink = this.options.itemLink || this.itemLink;
        this.itemTitle = this.options.itemTitle || this.itemTitle;
        this.followLinkOnSelect = this.options.followLinkOnSelect || this.followLinkOnSelect;
        this.source = this.options.source;
        this.delay = this.options.delay;
        this.theme = this.options.theme && this.options.themes && this.options.themes[this.options.theme] || Typeahead.defaults.themes[Typeahead.defaults.theme];
        this.$menu = $(this.options.menu || this.theme.menu);
        this.$appendTo = this.options.appendTo ? $(this.options.appendTo) : null;
        this.fitToElement = typeof this.options.fitToElement == 'boolean' ? this.options.fitToElement : false;
        this.shown = false;
        this.listen();
        this.showHintOnFocus = typeof this.options.showHintOnFocus == 'boolean' || this.options.showHintOnFocus === 'all' ? this.options.showHintOnFocus : false;
        this.afterSelect = this.options.afterSelect;
        this.afterEmptySelect = this.options.afterEmptySelect;
        this.addItem = false;
        this.value = this.$element.val() || this.$element.text();
        this.keyPressed = false;
        this.focused = this.$element.is(':focus');
        this.changeInputOnSelect = this.options.changeInputOnSelect || this.changeInputOnSelect;
        this.changeInputOnMove = this.options.changeInputOnMove || this.changeInputOnMove;
        this.openLinkInNewTab = this.options.openLinkInNewTab || this.openLinkInNewTab;
        this.selectOnBlur = this.options.selectOnBlur || this.selectOnBlur;
        this.showCategoryHeader = this.options.showCategoryHeader || this.showCategoryHeader;
    };

    Typeahead.prototype = {

        constructor: Typeahead,


        setDefault: function (val) {
            // var val = this.$menu.find('.active').data('value');
            this.$element.data('active', val);
            if (this.autoSelect || val) {
                var newVal = this.updater(val);
                // Updater can be set to any random functions via "options" parameter in constructor above.
                // Add null check for cases when updater returns void or undefined.
                if (!newVal) {
                    newVal = '';
                }
                this.$element
                    .val(this.displayText(newVal) || newVal)
                    .text(this.displayText(newVal) || newVal)
                    .change();
                this.afterSelect(newVal);
            }
            return this.hide();
        },

        select: function () {
            var val = this.$menu.find('.active').data('value');

            this.$element.data('active', val);
            if (this.autoSelect || val) {
                var newVal = this.updater(val);
                // Updater can be set to any random functions via "options" parameter in constructor above.
                // Add null check for cases when updater returns void or undefined.
                if (!newVal) {
                    newVal = '';
                }

                if (this.changeInputOnSelect) {
                    this.$element
                        .val(this.displayText(newVal) || newVal)
                        .text(this.displayText(newVal) || newVal)
                        .change();
                }

                if (this.followLinkOnSelect && this.itemLink(val)) {
                    if (this.openLinkInNewTab) {
                        window.open(this.itemLink(val), '_blank');
                    } else {
                        document.location = this.itemLink(val);
                    }
                    this.afterSelect(newVal);
                } else if (this.followLinkOnSelect && !this.itemLink(val)) {
                    this.afterEmptySelect(newVal);
                } else {
                    this.afterSelect(newVal);
                }
            } else {
                this.afterEmptySelect();
            }

            return this.hide();
        },

        updater: function (item) {
            return item;
        },

        setSource: function (source) {
            this.source = source;
        },

        show: function () {
            var pos = $.extend({}, this.$element.position(), {
                height: this.$element[0].offsetHeight
            });

            var scrollHeight = typeof this.options.scrollHeight == 'function' ?
                this.options.scrollHeight.call() :
                this.options.scrollHeight;

            var element;
            if (this.shown) {
                element = this.$menu;
            } else if (this.$appendTo) {
                element = this.$menu.appendTo(this.$appendTo);
                this.hasSameParent = this.$appendTo.is(this.$element.parent());
            } else {
                element = this.$menu.insertAfter(this.$element);
                this.hasSameParent = true;
            }

            if (!this.hasSameParent) {
                // We cannot rely on the element position, need to position relative to the window
                element.css('position', 'fixed');
                var offset = this.$element.offset();
                pos.top = offset.top;
                pos.left = offset.left;
            }
            // The rules for bootstrap are: 'dropup' in the parent and 'dropdown-menu-right' in the element.
            // Note that to get right alignment, you'll need to specify `menu` in the options to be:
            // '<ul class="typeahead dropdown-menu" role="listbox"></ul>'
            var dropup = $(element).parent().hasClass('dropup');
            var newTop = dropup ? 'auto' : (pos.top + pos.height + scrollHeight);
            var right = $(element).hasClass('dropdown-menu-right');
            var newLeft = right ? 'auto' : pos.left;
            // it seems like setting the css is a bad idea (just let Bootstrap do it), but I'll keep the old
            // logic in place except for the dropup/right-align cases.
            element.css({ top: newTop, left: newLeft }).show();

            if (this.options.fitToElement === true) {
                element.css('width', this.$element.outerWidth() + 'px');
            }

            this.shown = true;
            return this;
        },

        hide: function () {
            this.$menu.hide();
            this.shown = false;
            return this;
        },

        lookup: function (query) {
            if (typeof(query) != 'undefined' && query !== null) {
                this.query = query;
            } else {
                this.query = this.$element.val();
            }

            if (this.query.length < this.options.minLength && !this.options.showHintOnFocus) {
                return this.shown ? this.hide() : this;
            }

            var worker = $.proxy(function () {

                // Bloodhound (since 0.11) needs three arguments.
                // Two of them are callback functions (sync and async) for local and remote data processing
                // see https://github.com/twitter/typeahead.js/blob/master/src/bloodhound/bloodhound.js#L132
                if ($.isFunction(this.source) && this.source.length === 3) {
                    this.source(this.query, $.proxy(this.process, this), $.proxy(this.process, this));
                } else if ($.isFunction(this.source)) {
                    this.source(this.query, $.proxy(this.process, this));
                } else if (this.source) {
                    this.process(this.source);
                }
            }, this);

            clearTimeout(this.lookupWorker);
            this.lookupWorker = setTimeout(worker, this.delay);
        },

        process: function (items) {
            var that = this;

            items = $.grep(items, function (item) {
                return that.matcher(item);
            });

            items = this.sorter(items);

            if (!items.length && !this.options.addItem) {
                return this.shown ? this.hide() : this;
            }

            if (items.length > 0) {
                this.$element.data('active', items[0]);
            } else {
                this.$element.data('active', null);
            }

            if (this.options.items != 'all') {
                items = items.slice(0, this.options.items);
            }

            // Add item
            if (this.options.addItem) {
                items.push(this.options.addItem);
            }

            return this.render(items).show();
        },

        matcher: function (item) {
            var it = this.displayText(item);
            return ~it.toLowerCase().indexOf(this.query.toLowerCase());
        },

        sorter: function (items) {
            var beginswith = [];
            var caseSensitive = [];
            var caseInsensitive = [];
            var item;

            while ((item = items.shift())) {
                var it = this.displayText(item);
                if (!it.toLowerCase().indexOf(this.query.toLowerCase())) {
                    beginswith.push(item);
                } else if (~it.indexOf(this.query)) {
                    caseSensitive.push(item);
                } else {
                    caseInsensitive.push(item);
                }
            }

            return beginswith.concat(caseSensitive, caseInsensitive);
        },

        highlighter: function (item) {
            var text = this.query;
            if (text === '') {
                return item;
            }
            var matches = item.match(/(>)([^<]*)(<)/g);
            var first = [];
            var second = [];
            var i;
            if (matches && matches.length) {
                // html
                for (i = 0; i < matches.length; ++i) {
                    if (matches[i].length > 2) {// escape '><'
                        first.push(matches[i]);
                    }
                }
            } else {
                // text
                first = [];
                first.push(item);
            }
            text = text.replace((/[\(\)\/\.\*\+\?\[\]]/g), function (mat) {
                return '\\' + mat;
            });
            var reg = new RegExp(text, 'g');
            var m;
            for (i = 0; i < first.length; ++i) {
                m = first[i].match(reg);
                if (m && m.length > 0) {// find all text nodes matches
                    second.push(first[i]);
                }
            }
            for (i = 0; i < second.length; ++i) {
                item = item.replace(second[i], second[i].replace(reg, '<strong>$&</strong>'));
            }
            return item;
        },

        render: function (items) {
            var that = this;
            var self = this;
            var activeFound = false;
            var data = [];
            var _category = that.options.separator;

            $.each(items, function (key, value) {
                // inject separator
                if (key > 0 && value[_category] !== items[key - 1][_category]) {
                    data.push({
                        __type: 'divider'
                    });
                }

                if (this.showCategoryHeader) {
                    // inject category header
                    if (value[_category] && (key === 0 || value[_category] !== items[key - 1][_category])) {
                        data.push({
                            __type: 'category',
                            name: value[_category]
                        });
                    }
                }

                data.push(value);
            });

            items = $(data).map(function (i, item) {
                    if ((item.__type || false) == 'category'){
                        return $(that.options.headerHtml || that.theme.headerHtml).text(item.name)[0];
                    }

                    if ((item.__type || false) == 'divider'){
                        return $(that.options.headerDivider || that.theme.headerDivider)[0];
                    }

                    var text = self.displayText(item);
                    i = $(that.options.item || that.theme.item).data('value', item);
                    i.find(that.options.itemContentSelector || that.theme.itemContentSelector)
                        .addBack(that.options.itemContentSelector || that.theme.itemContentSelector)
                        .html(that.highlighter(text, item));
                    if(that.options.followLinkOnSelect) {
                        i.find('a').attr('href', self.itemLink(item));
                    }
                    i.find('a').attr('title', self.itemTitle(item));
                    if (text == self.$element.val()) {
                        i.addClass('active');
                        self.$element.data('active', item);
                        activeFound = true;
                    }
                    return i[0];
                });

            if (this.autoSelect && !activeFound) {
                items.filter(':not(.dropdown-header)').first().addClass('active');
                this.$element.data('active', items.first().data('value'));
            }
            this.$menu.html(items);
            return this;
        },

        displayText: function (item) {
            return typeof item !== 'undefined' && typeof item.name != 'undefined' ? item.name : item;
        },

        itemLink: function (item) {
            return null;
        },

        itemTitle: function (item) {
            return null;
        },

        next: function (event) {
            var active = this.$menu.find('.active').removeClass('active');
            var next = active.next();

            if (!next.length) {
                next = $(this.$menu.find($(this.options.item || this.theme.item).prop('tagName'))[0]);
            }

            while (next.hasClass('divider') || next.hasClass('dropdown-header')) {
                next = next.next();
            }

            next.addClass('active');
            // added for screen reader
            var newVal = this.updater(next.data('value'));
            if (this.changeInputOnMove) {
                this.$element.val(this.displayText(newVal) || newVal);
            }
        },

        prev: function (event) {
            var active = this.$menu.find('.active').removeClass('active');
            var prev = active.prev();

            if (!prev.length) {
                prev = this.$menu.find($(this.options.item || this.theme.item).prop('tagName')).last();
            }

            while (prev.hasClass('divider') || prev.hasClass('dropdown-header')) {
                prev = prev.prev();
            }

            prev.addClass('active');
            // added for screen reader
            var newVal = this.updater(prev.data('value'));
            if (this.changeInputOnMove) {
                this.$element.val(this.displayText(newVal) || newVal);
            }
        },

        listen: function () {
            this.$element
                .on('focus.bootstrap3Typeahead', $.proxy(this.focus, this))
                .on('blur.bootstrap3Typeahead', $.proxy(this.blur, this))
                .on('keypress.bootstrap3Typeahead', $.proxy(this.keypress, this))
                .on('propertychange.bootstrap3Typeahead input.bootstrap3Typeahead', $.proxy(this.input, this))
                .on('keyup.bootstrap3Typeahead', $.proxy(this.keyup, this));

            if (this.eventSupported('keydown')) {
                this.$element.on('keydown.bootstrap3Typeahead', $.proxy(this.keydown, this));
            }

            var itemTagName = $(this.options.item || this.theme.item).prop('tagName');
            if ('ontouchstart' in document.documentElement && 'onmousemove' in document.documentElement) {
		        this.$menu
		            .on('touchstart', itemTagName, $.proxy(this.touchstart, this))
		            .on('touchend', itemTagName, $.proxy(this.click, this))
		            .on('click', $.proxy(this.click, this))
		            .on('mouseenter', itemTagName, $.proxy(this.mouseenter, this))
		            .on('mouseleave', itemTagName, $.proxy(this.mouseleave, this))
		            .on('mousedown', $.proxy(this.mousedown,this));
	        } else if ('ontouchstart' in document.documentElement) {
		        this.$menu
		            .on('touchstart', itemTagName, $.proxy(this.touchstart, this))
		            .on('touchend', itemTagName, $.proxy(this.click, this));
	        } else {
                this.$menu
                    .on('click', $.proxy(this.click, this))
                    .on('mouseenter', itemTagName, $.proxy(this.mouseenter, this))
                    .on('mouseleave', itemTagName, $.proxy(this.mouseleave, this))
                    .on('mousedown', $.proxy(this.mousedown, this));
            }
        },

        destroy: function () {
            this.$element.data('typeahead', null);
            this.$element.data('active', null);
            this.$element
                .unbind('focus.bootstrap3Typeahead')
                .unbind('blur.bootstrap3Typeahead')
                .unbind('keypress.bootstrap3Typeahead')
                .unbind('propertychange.bootstrap3Typeahead input.bootstrap3Typeahead')
                .unbind('keyup.bootstrap3Typeahead');

            if (this.eventSupported('keydown')) {
                this.$element.unbind('keydown.bootstrap3-typeahead');
            }

            this.$menu.remove();
            this.destroyed = true;
        },

        eventSupported: function (eventName) {
            var isSupported = eventName in this.$element;
            if (!isSupported) {
                this.$element.setAttribute(eventName, 'return;');
                isSupported = typeof this.$element[eventName] === 'function';
            }
            return isSupported;
        },

        move: function (e) {
            if (!this.shown) {
                return;
            }

            switch (e.keyCode) {
                case 9: // tab
                case 13: // enter
                case 27: // escape
                    e.preventDefault();
                    break;

                case 38: // up arrow
                    // with the shiftKey (this is actually the left parenthesis)
                    if (e.shiftKey) {
                        return;
                    }
                    e.preventDefault();
                    this.prev();
                    break;

                case 40: // down arrow
                    // with the shiftKey (this is actually the right parenthesis)
                    if (e.shiftKey) {
                        return;
                    }
                    e.preventDefault();
                    this.next();
                    break;
            }
        },

        keydown: function (e) {
            /**
             * Prevent to make an ajax call while copying and pasting.
             *
             * @author Simone Sacchi
             * @version 2018/01/18
             */
            if (e.keyCode === 17) { // ctrl
                return;
            }
            this.keyPressed = true;
            this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40, 38, 9, 13, 27]);
            if (!this.shown && e.keyCode == 40) {
                this.lookup();
            } else {
                this.move(e);
            }
        },

        keypress: function (e) {
            if (this.suppressKeyPressRepeat) {
                return;
            }
            this.move(e);
        },

        input: function (e) {
            // This is a fixed for IE10/11 that fires the input event when a placehoder is changed
            // (https://connect.microsoft.com/IE/feedback/details/810538/ie-11-fires-input-event-on-focus)
            var currentValue = this.$element.val() || this.$element.text();
            if (this.value !== currentValue) {
                this.value = currentValue;
                this.lookup();
            }
        },

        keyup: function (e) {
            if (this.destroyed) {
                return;
            }
            switch (e.keyCode) {
                case 40: // down arrow
                case 38: // up arrow
                case 16: // shift
                case 17: // ctrl
                case 18: // alt
                    break;

                case 9: // tab
                    if (!this.shown || (this.showHintOnFocus && !this.keyPressed)) {
                        return;
                    }
                    this.select();
                    break;
                case 13: // enter
                    if (!this.shown) {
                        return;
                    }
                    this.select();
                    break;

                case 27: // escape
                    if (!this.shown) {
                        return;
                    }
                    this.hide();
                    break;
            }

        },

        focus: function (e) {
            if (!this.focused) {
                this.focused = true;
                this.keyPressed = false;
                if (this.options.showHintOnFocus && this.skipShowHintOnFocus !== true) {
                    if (this.options.showHintOnFocus === 'all') {
                        this.lookup('');
                    } else {
                        this.lookup();
                    }
                }
            }
            if (this.skipShowHintOnFocus) {
                this.skipShowHintOnFocus = false;
            }
        },

        blur: function (e) {
            if (!this.mousedover && !this.mouseddown && this.shown) {
                if (this.selectOnBlur) {
                    this.select();
                }
                this.hide();
                this.focused = false;
                this.keyPressed = false;
            } else if (this.mouseddown) {
                // This is for IE that blurs the input when user clicks on scroll.
                // We set the focus back on the input and prevent the lookup to occur again
                this.skipShowHintOnFocus = true;
                this.$element.focus();
                this.mouseddown = false;
            }
        },

        click: function (e) {
            e.preventDefault();
            this.skipShowHintOnFocus = true;
            this.select();
            this.$element.focus();
            this.hide();
        },

        mouseenter: function (e) {
            this.mousedover = true;
            this.$menu.find('.active').removeClass('active');
            $(e.currentTarget).addClass('active');
        },

        mouseleave: function (e) {
            this.mousedover = false;
            if (!this.focused && this.shown) {
                this.hide();
            }
        },

        /**
         * We track the mousedown for IE. When clicking on the menu scrollbar, IE makes the input blur thus hiding the menu.
         */
        mousedown: function (e) {
            this.mouseddown = true;
            this.$menu.one('mouseup', function (e) {
                // IE won't fire this, but FF and Chrome will so we reset our flag for them here
                this.mouseddown = false;
            }.bind(this));
        },

        touchstart: function (e) {
            e.preventDefault();
            this.$menu.find('.active').removeClass('active');
            $(e.currentTarget).addClass('active');
        },

        touchend: function (e) {
            e.preventDefault();
            this.select();
            this.$element.focus();
        }

    };


    /* TYPEAHEAD PLUGIN DEFINITION
     * =========================== */

    var old = $.fn.typeahead;

    $.fn.typeahead = function (option) {
        var arg = arguments;
        if (typeof option == 'string' && option == 'getActive') {
            return this.data('active');
        }
        return this.each(function () {
            var $this = $(this);
            var data = $this.data('typeahead');
            var options = typeof option == 'object' && option;
            if (!data) {
                $this.data('typeahead', (data = new Typeahead(this, options)));
            }
            if (typeof option == 'string' && data[option]) {
                if (arg.length > 1) {
                    data[option].apply(data, Array.prototype.slice.call(arg, 1));
                } else {
                    data[option]();
                }
            }
        });
    };

    Typeahead.defaults = {
        source: [],
        items: 8,
        minLength: 1,
        scrollHeight: 0,
        autoSelect: true,
        afterSelect: $.noop,
        afterEmptySelect: $.noop,
        addItem: false,
        followLinkOnSelect: false,
        delay: 0,
        separator: 'category',
        changeInputOnSelect: true,
        changeInputOnMove: true,
        openLinkInNewTab: false,
        selectOnBlur: true,
        showCategoryHeader: true,
        theme: "bootstrap3",
        themes: {
        bootstrap3: {
            menu: '<ul class="typeahead dropdown-menu" role="listbox"></ul>',
            item: '<li><a class="dropdown-item" href="#" role="option"></a></li>',
            itemContentSelector: "a",
            headerHtml: '<li class="dropdown-header"></li>',
            headerDivider: '<li class="divider" role="separator"></li>'
        },
        bootstrap4: {
            menu: '<div class="typeahead dropdown-menu" role="listbox"></div>',
            item: '<button class="dropdown-item" role="option"></button>',
            itemContentSelector: '.dropdown-item',
            headerHtml: '<h6 class="dropdown-header"></h6>',
            headerDivider: '<div class="dropdown-divider"></div>'
        }
    }
};

    $.fn.typeahead.Constructor = Typeahead;

    /* TYPEAHEAD NO CONFLICT
     * =================== */

    $.fn.typeahead.noConflict = function () {
        $.fn.typeahead = old;
        return this;
    };


    /* TYPEAHEAD DATA-API
     * ================== */

    $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
        var $this = $(this);
        if ($this.data('typeahead')) {
            return;
        }
        $this.typeahead($this.data());
    });

}));

三、调用

<!--
@Html_Name: visualizationData
@Description: 
@Author: whz
@Version:1.0 2020/6/2  14:31
-->
<!DOCTYPE html>
<!-- saved from url=(0050)https://yyhsong.github.io/iDataV/case09/index.html -->
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
	<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no">
	<title></title>
	<link rel="stylesheet" href ="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">  
	<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
	<script src="./bootstrap3-typeahead.min.js"></script>
</head>
<body >
<div class="well">
	<input type="text" class="span3" id="search" data-provide="typeahead" data-items="9" />
</div>
</body>
<script>
var subjects = ['PHP', 'MySQL', 'SQL', 'PostgreSQL', 'HTML', 'CSS', 'HTML5', 'CSS3', 'JSON']; 
$('#search').typeahead(
	{
		source: subjects,
		afterSelect: function(args){
			alert(args);
		}
	}
)
	</script>
</html>

四、demo效果

五、bootstrap3-typeahead相关属性操做

NameTypeDefaultDescription
sourcearray, function[]The data source to query against. May be an array of strings, an array of JSON object with a name property or a function. The function accepts two arguments, the query value in the input field and the process callback. The function may be used synchronously by returning the data source directly or asynchronously via the process callback's single argument.
itemsnumber8The max number of items to display in the dropdown. Can also be set to 'all'
minLengthnumber1The minimum character length needed before triggering autocomplete suggestions. You can set it to 0 so suggestion are shown even when there is no text when lookup function is called.
showHintOnFocusboolean or "all"falseIf hints should be shown as soon as the input gets focus. If set to true, all match will be shown. If set to "all", it will display all hints, not filtering them by the current text. This can be used when you want an input that behaves a bit like a combo box plus auto completion as you type to filter the choices.
scrollHeightnumber, function0Number of pixels the scrollable parent container scrolled down (scrolled out the viewport).
matcherfunctioncase insensitiveThe method used to determine if a query matches an item. Accepts a single argument, the item against which to test the query. Access the current query with this.query. Return a boolean true if query is a match.
sorterfunctionexact match, case sensitive, case insensitiveMethod used to sort autocomplete results. Accepts a single argument items and has the scope of the typeahead instance. Reference the current query with this.query.
updaterfunctionreturns selected itemThe method used to return selected item. Accepts a single argument, the item and has the scope of the typeahead instance.
highlighterfunctionhighlights all default matchesMethod used to highlight autocomplete results. Accepts a single argument item and has the scope of the typeahead instance. Should return html.
displayTextfunctionitem.name || itemMethod used to get textual representation of an item of the sources. Accepts a single argument item and has the scope of the typeahead instance. Should return a String.
autoSelectbooleantrueAllows you to dictate whether or not the first suggestion is selected automatically. Turning autoselect off also means that the input won't clear if nothing is selected and enter or tab is hit.
afterSelectfunction$.noop()Call back function to execute after selected an item. It gets the current active item in parameter if any.
delayinteger0Adds a delay between lookups.
appendTojQuery elementnullBy defaut, the menu is added right after the input element. Use this option to add the menu to another div. It should not be used if you want to use bootstrap dropup or dropdown-menu-right classes.
fitToElementbooleanfalseSet to true if you want the menu to be the same size than the input it is attached to.
addItemJSON objectfalseAdds an item to the end of the list, for example "New Entry". This could be used, for example, to pop a dialog when an item is not found in the list of data. Example: http://cl.ly/image/2u170I1q1G3A/addItem.png
changeInputOnSelectbooleantruePut the selected value text representation in the input
changeInputOnMovebooleantruePut the active value text representation in the input
openLinkInNewTabbooleanfalseOpen links in a new window/tab
selectOnBlurbooleantrueAutomatically select the active value on blur
showCategoryHeaderbooleantrueShow categories header in the dropdown menu

详细介绍见:https://github.com/bassjobsen/Bootstrap-3-Typeahead

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值