web-dev-qa-db-ja.com

Twitter bootstrap=複数の値を先行入力しますか?

Twitter Bootstrap= Jqueryを使用しています。テキストエリアに[〜#〜] typeahead [〜#〜]関数を使用します、これは非常に簡単に作業できるようになりましたが、複数選択を許可するためにも必要です

つまり、オートコンプリートから1つのWordを選択した後、余分なスペースを追加してtextareaに戻り、もう一度入力を開始すると、もう一度入力するように求められます。

ここにJSビンがあります: http://jsbin.com/ewubuk/1/edit (内部には特別なものはありません)。

先行入力による複数選択を可能にする簡単な解決策はありますか?はいの場合、どのように?

前もって感謝します。

44
denislexic

Editそれについてはすでにプルがありました: https://github.com/Twitter/bootstrap/pull/2007


Typeaheadにプロキシを使用することにより、目的の動作にアプローチできます。 Demo(jsfiddle)

var $myTextarea = $('#myTextarea');

$('.typeahead').typeahead({
    source: source,
    updater: function(item) {
        $myTextarea.append(item, ' ');
        return '';
    }
});

updaterメソッドはこの種のものを対象としているので、表示されるものを返すだけです。


または本当にすべてを同じ入力要素に入れたい場合は、現在入力されている要素とのみ一致するようにメソッドをオーバーライドする必要があります: デモ(jsfiddle)

function extractor(query) {
    var result = /([^,]+)$/.exec(query);
    if(result && result[1])
        return result[1].trim();
    return '';
}

$('.typeahead').typeahead({
    source: source,
    updater: function(item) {
        return this.$element.val().replace(/[^,]*$/,'')+item+',';
    },
    matcher: function (item) {
      var tquery = extractor(this.query);
      if(!tquery) return false;
      return ~item.toLowerCase().indexOf(tquery.toLowerCase())
    },
    highlighter: function (item) {
      var query = extractor(this.query).replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
        return '<strong>' + match + '</strong>'
      })
    }
});

最後に特殊文字の後に入力する必要があるため、これはばかではありません。

88
Sherbrow

これは、選択ボックスの優れた代替品です。

http://ivaynberg.github.io/select2/

(複数値バージョンを使用する場合。)

12
James Head

一番上の答えは、最新の typeahead ではもう機能しないようですので、以下を提供します。

[〜#〜] fiddle [〜#〜]

function MultiTypeahead(id, data, trigger, vertAdjustMenu)
{
    trigger = (undefined !== trigger) ? trigger : '';
    var validChars = /^[a-zA-Z]+$/;


    function extractor(query)
    {
        var result = (new RegExp('([^,; \r\n]+)$')).exec(query);
        if(result && result[1])
            return result[1].trim();
        return '';
    }

    var lastUpper = false;
    function strMatcher(id, strs) 
    {
        return function findMatches(q, sync, async) 
        {
            var pos = $(id).caret('pos');
            q = (0 < pos) ? extractor(q.substring(0, pos)) : '';

            if (q.length <= trigger.length)
                return;

            if (trigger.length)
            {
                if(trigger != q.substr(0, trigger.length))
                    return;

                q = q.substr(trigger.length);
            }

            if (!q.match(validChars))
                return;

            var firstChar = q.substr(0, 1);
            lastUpper = (firstChar === firstChar.toUpperCase() && firstChar !== firstChar.toLowerCase());

            var cpos = $(id).caret('position');
            $(id).parent().find('.tt-menu').css('left', cpos.left + 'px');
            if (vertAdjustMenu)
                $(id).parent().find('.tt-menu').css('top', (cpos.top + cpos.height) + 'px');

            var matches = [];
            var matches = [], substrRegex = new RegExp(q, 'i');
            $.each(strs, function(i, str) 
            {
                if (str.length > q.length && substrRegex.test(str))
                    matches.Push(str);
            });

            if (!matches.length)
                return;

            sync(matches);
        };
    };

    var lastVal = '';
    var lastPos = 0;
    function beforeReplace(event, data)
    {
        lastVal = $(id).val();
        lastPos = $(id).caret('pos');
        return true;
    }

    function onReplace(event, data)
    {            
        if (!data || !data.length)
            return;

        if (!lastVal.length)
            return;

        var root = lastVal.substr(0, lastPos);
        var post = lastVal.substr(lastPos);

        var typed = extractor(root);
        if (!lastUpper && typed.length >= root.length && 0 >= post.length)
            return;

        var str = root.substr(0, root.length - typed.length);

        str += lastUpper ? (data.substr(0, 1).toUpperCase() + data.substr(1)) : data;
        var cursorPos = str.length;

        str += post;

        $(id).val(str);
        $(id).caret('pos', cursorPos);      
    }

    this.typeahead = 
        $(id).typeahead({hint: false, highlight: false}, {'limit': 5, 'source': strMatcher(id, data)})
                .on('typeahead:beforeselect', beforeReplace)
                .on('typeahead:beforeautocomplete', beforeReplace)
                .on('typeahead:beforecursorchange', beforeReplace)
                .on('typeahead:selected', function(event,data){setTimeout(function(){ onReplace(event, data); }, 0);})
                .on('typeahead:autocompleted', onReplace)
                .on('typeahead:cursorchange', onReplace)
                ;
}

EDIT:前のコードには余分なものが多すぎるので、最小限の作業例に絞り込みました。

これ は以前に投稿されたものです。

3
bob2

プラグインを編集して複数の選択を許可し(ドロップダウンメニューを閉じないでください)、選択した値をコンマで区切って追加できると思います。唯一の問題は、ドロップダウンを閉じるタイミングがわからないことです。

1
superlukas

私はパーティーに遅れましたが、これがBootstrap v4。のために思いついたものです。また、d3が必要です(jQueryにあまり詳しくないので))。

http://sumneuron.gitlab.io/multitags/で実行されている例を見ることができますenter image description here

いくつかの便利な機能があり、明確に書かれており、これを見つけた人なら誰でも良いスタートを切るはずです。特に、タグ付けの実装方法について興味がある場合。

enter image description here

コードは https://gitlab.com/SumNeuron/multitags/pipelines で入手できます。

ロジックはおおよそ次のとおりです。

if keydown in [enter, ","]:
    // logic of function "doneTyping" 
    text = parse(text) // get text from textarea and grab latest value
    if text is valid:
        renderTag(text) // put the text in a tag element
        updateHiddenForm(text) // update the hidden form to include the tag
    else:
        notifyUserOfInvalidTag(text) // alert user
else:
    // logic of function "stillTyping" 
    suggest = bloodhoundSearch(text) // use Twitter typeahead
    updateSuggestionBox(suggest) // display results from typeahead
0
SumNeuron