2012-09-30 30 views
43

我使用Twitter的引導與jQuery。 我想用預輸入功能一個textarea,我得到了超級輕鬆的工作。 但我也需要它允許多重選擇Twitter引導鍵入多個值?

由此我的意思是,在我從自動完成中選擇一個單詞之後,它將我帶回一個額外的空間,然後如果我再次打開,它會讓我再次執行它。

這裏是一個JS bin:http://jsbin.com/ewubuk/1/edit (沒什麼特別的)。

有沒有簡單的解決方案,以便與預輸入多重選擇?如果是,如何?

在此先感謝。

回答

87

編輯已經有了另外一個關於拉:Demo (jsfiddle)

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

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

我認爲updater方法:https://github.com/twitter/bootstrap/pull/2007


您可以通過使用代理的預輸入接近期望的行爲是爲了這種事情,你只是返回將顯示的內容。


或者,如果你真的想要的一切是在同一輸入元素,你就必須重寫更多的方法,使其只在當前類型的元素相匹配:Demo (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>' 
     }) 
    } 
}); 

這一個不是白癡證明,因爲你必須在特殊字符後面輸入結尾。

+0

這很完美。謝謝! – denislexic

+1

太棒了,男人!正是我需要的。 –

+0

非常感謝! –

1

我想你可以編輯該插件允許多重選擇(不要關閉下拉菜單),並添加以逗號分隔的選定值。我看到的唯一問題是您不知道何時關閉下拉菜單。

12

這是一個選擇框的最佳替代品:

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

(如果使用多值版本)。

+2

請注意,typehead的作者表示他們從未打算添加此功能。他們實際上也推薦在這種情況下使用Select2。 https://github.com/twitter/typeahead.js/issues/135 – andrewtweber

1

頂端回答似乎並沒有使用最新的工作了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) 
       ; 
} 

編輯:實現上面的代碼中有太多額外的東西,我把範圍縮小到最小的工作示例。

This是以前發佈的內容。