Отображение нескольких столбцов в Select2

Я использую select2, и я хотел бы показать многоцветную таблицу в качестве раскрывающегося списка, поэтому мне нужна ширина выпадающего контейнера для имеют большую (большую) ширину, чем сам вход

Можно ли это сделать?

Кроме того, я хотел бы показать таблицу с несколькими столбцами. В примере с фильмами я увидел, что в функции formatResult вы создаете новую таблицу для каждой строки.

Можно ли включить каждую строку в ту же таблицу, чтобы каждая ячейка имела одинаковую ширину? Мне нужно было бы установить некоторый шаблон, чтобы содержать строки или что-то в этом роде.

То, что я хочу достичь, - это небольшой ввод, чтобы показать код объекта, а также большой выпадающий список, чтобы показать еще несколько столбцов.

-

вот связанная с этим проблема в github: https://github.com/ivaynberg/select2/issues/1314

Ответ 1

У меня еще не было успеха с наличием строки с фиксированным заголовком над столбцами, чтобы выступать в качестве типичной строки заголовка таблицы, но с точки зрения фактического получения столбцов там я упоминал этот запрос функции на Github, где пользователь trebuchetty ссылается на использование стилей сетки bootstrap, таких как col-md-6 (bootstrap versions >= 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>';
},

результат выше - ссылка на элемент в массиве элементов, отображаемых в раскрывающемся меню

Ответ 2

formatresult не работал у меня! Но templateResult отлично работает, как это, с формой данных PHP в сгенерированном HTML (не ajax-содержимом).

Вот код woorking для меня, я разделяю свои столбцы на трубку char (у нас может быть более двух столбцов):

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;
    }
}); 

Ответ 3

Если вы используете 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>

Ответ 4

Я хотел дать свое решение, которое, надеюсь, поможет другим.

Использование табличного стиля Select2 v4 и многоколоночного поиска. Это использует локальные данные JSON.

Краткий обзор того, как это работает:

Есть 2 функции. matcher функция и formatSelect.

Функция matcher используется для запроса. Он проверит каждое слово запроса, чтобы увидеть, есть ли совпадение в любой из строк. В настоящее время настроено возвращать любую строку, которая соответствует по крайней мере 1 слову.

Функция formatSelect запускается после того, как matcher вернуло все подходящие строки (все строки, если нет запроса). formatSelect добавляет столбцы заголовка в первую строку данных, если это первая отображаемая строка.

Таблица в этом случае использует ширину столбца начальной загрузки для структуры.

Код:

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

Ответ 5

Вот мои решения. Моя версия 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;
}

Все это.

Ответ 6

см. это может быть полезно, здесь компонент для создания столбцов в select2 like structure https://github.com/suriyagp/Grid-Select

Ответ 7

Мой пример (основанный на ответе Меломана) может помочь кому-то другому:

// 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];
    }
});