在Select2中显示多个列

时间:2013-05-15 03:22:37

标签: javascript jquery-select2 dropdownbox

我正在使用select2并且我想将多色表显示为下拉列表,因此我需要下拉容器的宽度与输入本身具有不同(更大)的宽度< / p>

有可能吗?

此外,我想展示一个包含多个列的表格。从电影示例中,我看到在formatResult函数中,您为每一行创建一个新表。

是否可以在同一个表中包含每一行,以便每个单元格具有相同的宽度?我需要设置一些模板来包含行或类似的东西。

我想要实现的是显示实体代码的小输入,以及显示更多列的大型下拉列表

-

这是关于github的相关问题:https://github.com/ivaynberg/select2/issues/1314

8 个答案:

答案 0 :(得分:4)

我还没有取得任何成功,因为在列上方有一个固定的标题行作为典型的表标题行,但就实际获取列而言,我提到了this feature request on Github用户trebuchetty暗示使用bootstrap的网格样式,如col-md-6(bootstrap version&gt; = 3)。

我在select2选项中尝试了以下操作,似乎效果很好:

formatResult: function(result) {
    return '<div class="row">' +
           '<div class="col-md-6">' + result.name + '</div>' +
           '<div class="col-md-6">' + result.manager + '</div>' +
           '</div>';
},
上面的

结果是对下拉列表中显示的项目数组中元素的引用

答案 1 :(得分:3)

formatresult 对我不起作用!但 templateResult可以正常运行 ,生成HTML格式的PHP数据格式(不是ajax内容)。

这是我的代码,我用管道字符分隔我的列(我们可以有超过2列):

html(来自PHP):

<option value="...">
    column 1 text | column 2 text
</option>

javascript(jQuery):

$('#selectSubstance').select2({
    templateResult: function(data) {
        var r = data.text.split('|');
        var $result = $(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return $result;
    }
}); 

答案 2 :(得分:2)

如果您使用Select2 v3.5,这是一种解决方法:

function formatResultMulti(data) {
  var city = $(data.element).data('city');
  var classAttr = $(data.element).attr('class');
  var hasClass = typeof classAttr != 'undefined';
  classAttr = hasClass ? ' ' + classAttr : '';

  var $result = $(
    '<div class="row">' +
    '<div class="col-md-6 col-xs-6' + classAttr + '">' + data.text + '</div>' +
    '<div class="col-md-6 col-xs-6' + classAttr + '">' + city + '</div>' +
    '</div>'
  );
  return $result;
}

$(function() {
  $('#multi').select2({
    width: '100%',
    formatResult: formatResultMulti
  });
})
body{
  background-color: #455A64;
}

#multiWrapper {
  width: 300px;
  margin: 25px 0 0 25px;
}

.def-cursor {
  cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.0/select2.min.js"></script>
<div id='multiWrapper'>
  <select id="multi">
    <optgroup class='def-cursor' label='Country' data-city='City'>
      <option data-city="Athens" id="1" selected>Greece</option>
      <option data-city="Rome" "id="2 ">Italy</option>
  <option data-city="Paris " "id="3">France</option>
    </optgroup>
  </select>
</div>

答案 3 :(得分:1)

我想提出我希望能帮助他人的解决方案。

使用Select2 v4 tableish样式和多列搜索。 这使用本地JSON数据。

快速了解其工作原理:

有2个功能。 matcher函数和formatSelect

matcher函数用于查询。它将检查查询的每个单词,以查看是否在任何行中存在匹配项。目前设置为返回匹配atleaast 1个字的任何行。

一旦formatSelect返回所有匹配的行(如果没有查询则返回所有行),则运行matcher函数。 formatSelect在第一行数据上添加标题列,如果它是第一行的呈现。

本例中的表使用bootstrap列宽作为结构。

代码:

var firstEmptySelect = true;

function formatSelect(result) {
    if (!result.id) {
        if (firstEmptySelect) {
            console.log('showing row');
            firstEmptySelect = false;
            return '<div class="row">' +
                    '<div class="col-xs-3"><b>Client</b></div>' +
                    '<div class="col-xs-3"><b>Account</b></div>' +
                    '<div class="col-xs-3"><b>Deal</b></div>' +
                    '</div>';
        } else {
            console.log('skipping row');
            return false;
        }
        console.log('result');
        console.log(result);
    }
    return '<div class="row">' +
                 '<div class="col-xs-3">' + result.client_name + '</div>' +
                 '<div class="col-xs-3">' + result.account_name + '</div>' +
                 '<div class="col-xs-3">' + result.deal_name + '</div>' +
                 '</div>';      
}

function matcher(query, option) {
    firstEmptySelect = true;
    if (!query.term) {
        return option;
    }
    var has = true;
    var words = query.term.toUpperCase().split(" ");
    for (var i =0; i < words.length; i++){
        var word = words[i];
        has = has && (option.text.toUpperCase().indexOf(word) >= 0); 
    }
    if (has) return option;
    return false;
}

$('#selectAccountDeal').select2({
    data: {!! $deals !!},
    width: '100%',
    templateResult: formatSelect,
    templateSelection: formatSelect,
    escapeMarkup: function(m) { return m; },
    matcher: matcher
})

我的示例JSON数据

[{
    "text": "JL - o yea - Testing this deal",
    "id": 4,
    "client_name": "JL",
    "account_name": "o yea",
    "deal_name": "Testing this deal"
}, {
    "text": "JL - test - fj;askld fj",
    "id": 3,
    "client_name": "JL",
    "account_name": "test",
    "deal_name": "fj;askld fj"
}]

选择元素的HTML

<select id="selectAccountDeal" name="account_deal_id" placeholder="Select your Deal" required>
  <option></option>
</select>

select2下拉列表的示例

select2 table view

答案 4 :(得分:1)

这是我的解决方案。我的select2版本是4.0.3。

最终演示如下: select2-dropdown-table

在select2下拉列表打开时首先添加标题:

    var headerIsAppend = false;
    $('#stock').on('select2:open', function (e) {
        if (!headerIsAppend) {
            html = '<table class="table table-bordered" style="margin-top: 5px;margin-bottom: 0px;">\
                <tbody>\
                <tr>\
                    <td width="20%"><b>药品名称</b></td>\
                    <td width="10%"><b>成本价</b></td>\
                    <td width="20%"><b>供应商</b></td>\
                    <td width="10%"><b>批号</b></td>\
                    <td width="20%"><b>有效期</b></td>\
                    <td width="20%"><b>库存数量</b></td>\
                </tr >\
                </tbody>\
                </table>';
            $('.select2-search').append(html);
            $('.select2-results').addClass('stock');
            headerIsAppend = true;
        }
    });

然后

templateResult: function (repo) {
            if (repo.medicine) {
                var html = '<table class="table table-bordered" style="margin-bottom: 0px;">\
                <tbody>\
                <tr>\
                    <td width="20%">' + repo.medicine.name + '</td>\
                    <td width="10%">' + repo.costPrice + '</td>\
                    <td width="20%">' + repo.vendor + '</td>\
                    <td width="10%">' + repo.batchNum + '</td>\
                    <td width="20%">' + repo.expiredDate + '</td>\
                    <td width="20%">' + repo.quantity + '</td>\
                </tr >\
                </tbody>\
                </table>';
                return $(html);
            }
        },

剩下的工作就是调整css:

.stock .select2-results__option {
  padding: 0px 4px;
}

仅此而已。

答案 5 :(得分:0)

参考这可能有帮助,这里是一个组件,用于在select2之类的结构中创建列 https://github.com/suriyagp/Grid-Select

答案 6 :(得分:0)

我的例子(根据Meloman的回答)可以帮助别人:

// HTML
 <select 
    class="form-control select2" 
    data-col0htmldebut="<div class='col-md-6'>" 
    data-col0htmlfin="</div>" 
    data-col1htmldebut="<div class='col-md-2'>" 
    data-col1htmlfin="</div>" 
    data-col2htmldebut="<div class='col-md-4'>" 
    data-col2htmlfin="</div>">
          <option value="">Select...</option>
          <option value="-1">Text with no column</option>
          <option value="1">Column1__|__Col2__|__Col3</option>
          <option value="2">Column1__|__Col2__|__Col3</option>
 </select>

$("select.select2").select2({
    templateResult: function (data) {
        if (data.element == null) return data.text;


        /**************  Just one column handler **************/

        // __|__ text seperator between each col find ?
        var arrTexteOption = data.text.split('__|__');
        if (arrTexteOption.length <= 1) return data.text;


        /**************  Multi column handler **************/

        // Get select object
        var objSelect = $("#" + data.element.parentNode.id);

        // 4 column handled here
        var arrStyleColDébut = [];
        var arrStyleColFin = [];

        for (var i = 0; i < 4; i++)
        {
            if (objSelect.attr('data-col' + i + 'htmldebut'))   arrStyleColDébut.push(objSelect.data("col" + i + "htmldebut"));
            if (objSelect.attr('data-col' + i + 'htmlfin'))     arrStyleColFin.push(objSelect.data("col" + i + "htmlfin"));
        }

        if (arrTexteOption.length != arrStyleColDébut.length) return data.text;

        var $htmlResult = '<div class="row">';
        for (var i = 0; i < arrTexteOption.length; i++)
        {
            $htmlResult += arrStyleColDébut[i] + arrTexteOption[i] + arrStyleColFin[i];
        }
        $htmlResult += "</div>";

        return $($htmlResult);
    },
    templateSelection: function (data) {
        // Selection must display only the first col.
        return data.text.split('__|__')[0];
    }
});

答案 7 :(得分:0)

我使用SELECT2 V4。 感谢BrinkDaDrink的想法。我做了一些修改并简化了代码。 以下是我的示例:

        var firstEmptySelect = true; // Indicate header was create

        function s2FormatResult(item) {

            if (!item.id) {
                // trigger when remote query
                firstEmptySelect = true; // reset
                return item.text;
            }

            var $container; // This is custom templete container.

            // Create header
            if (firstEmptySelect) {

                firstEmptySelect = false;

                $container = $(
                    '<div class="row">' +
                    '<div class="col-xs-3"><b>Product ID</b></div>' +
                    '<div class="col-xs-3"><b>Product Name</b></div>' +
                    '</div>' +
                    '<div class="row">' +
                    '<div class="col-xs-3">' + item.id + '</div>' +
                    '<div class="col-xs-3">' + item.text + '</div>' +
                    '</div>'
                );

            }
            else {
                $container = $('<div class="row">' +
                    '<div class="col-xs-3">' + item.id + '</div>' +
                    '<div class="col-xs-3">' + item.text + '</div>' +
                    '</div>');
            }


          return $container
        }

It's look like this.