18

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

有可能这样做吗?

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

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

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

--

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

4

8 回答 8

7

格式结果对我不起作用!但是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;
    }
}); 

编辑 2021-06-28

如果您希望所选项目具有相同的视觉效果(关闭选择),请使用相同的语法templateSelection:

例如 :

$('#selectProduct').select2({            
    placeholder: 'Choose a product.',
    templateResult: function(data) {
        var r = data.text.split('| ');
        var result = jQuery(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return result;
    },
    templateSelection: function(data) {
        var r = data.text.split('| ');
        var result = jQuery(
            '<div class="row">' +
                '<div class="col-md-3">' + r[0] + '</div>' +
                '<div class="col-md-9">' + r[1] + '</div>' +
            '</div>'
        );
        return result;
    }
});
于 2016-10-13T17:26:04.790 回答
6

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

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

快速概述这是如何工作的:

有2个功能。matcher函数formatSelect和.

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

一旦返回了所有匹配的行(如果没有查询,则为所有行), 然后运行该formatSelect函数。如果第一行正在呈现,则在第一行数据上添加标题列。matcherformatSelect

在这种情况下,表格使用引导列宽作为结构。

编码:

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 表视图

于 2018-06-08T05:09:12.990 回答
5

如果您使用 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>

于 2018-01-23T08:36:33.357 回答
4

我还没有取得任何成功,在列上方有一个固定的标题行作为典型的表标题行,但就实际获取列而言,我在 Github 上提到了这个功能请求,其中用户 trebuchetty 暗示使用引导程序的网格样式,如 col-md-6(引导程序版本 >= 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>';
},

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

于 2014-01-30T14:01:56.943 回答
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>成本价&lt;/b></td>\
                    <td width="20%"><b>供应商&lt;/b></td>\
                    <td width="10%"><b>批号</b></td>\
                    <td width="20%"><b>有效期&lt;/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;
}

就这样。

于 2018-09-05T02:58:16.510 回答
0

参考这个它可能会有所帮助,这里是一个组件,可以在 select2 中创建列,如结构 https://github.com/suriyagp/Grid-Select

于 2014-11-10T13:15:41.637 回答
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
        }

它看起来像这样。

于 2019-11-04T08:14:35.810 回答
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];
    }
});
于 2018-02-14T10:13:39.507 回答