Выбрать все/Отменить выбор всего в плагине Bootstrap Select

<select id="divRatings" class="selectpicker" multiple title='Choose one of the following...' data-size="5" data-selected-text-format="count>2">
    <option value="All" selected="selected">All Ratings</option>
    <option value="EC">EC (Early Childhood)</option>
    <option value="E">E (Everyone)</option>
    <option value="E10+">E10+ (Everyone 10+)</option>
    <option value="T">T (Teen)</option>
    <option value="M">M (Mature)</option>
    <option value="AO">AO (Adults Only)</option>
</select>

В html выше есть опция со значением All. Я хочу выбрать все элементы, если этот параметр выбран, и отменить выбор всех, если я отменю выбор этого параметра.

Я думаю, это будет просто сделать, но я не могу понять, почему ничего не происходит на $('#divRatings').change(function(){//some logic});

Моя функция для выбора/отмены выбора элементов:

function toggleSelectAll(control) {
    if (control.val().indexOf("All,") > -1) {
        control.selectpicker('selectAll');
    } else {
        control.selectpicker('deselectAll');
    }
}

пример JSFiddle


person demo    schedule 23.01.2015    source источник


Ответы (8)


Проблема с вашим javascript заключается в том, что каждый раз, когда пользователь щелкает любую опцию, которую вы проверяете, если опция «Все рейтинги» все еще отмечена, вы также проверяете все остальные опции (даже если вы только что сняли отметку с какой-либо опции). И если флажок «Все рейтинги» снят, вы снимаете все остальные параметры. Так что на самом деле кликабельна только опция «Все оценки». Если вы выберете любую другую опцию, она сразу же будет отмечена/снята в вашем обработчике onchange.

Попробуйте этот код:

function toggleSelectAll(control) {
    var allOptionIsSelected = (control.val() || []).indexOf("All") > -1;
    function valuesOf(elements) {
        return $.map(elements, function(element) {
            return element.value;
        });
    }

    if (control.data('allOptionIsSelected') != allOptionIsSelected) {
        // User clicked 'All' option
        if (allOptionIsSelected) {
            // Can't use .selectpicker('selectAll') because multiple "change" events will be triggered
            control.selectpicker('val', valuesOf(control.find('option')));
        } else {
            control.selectpicker('val', []);
        }
    } else {
        // User clicked other option
        if (allOptionIsSelected && control.val().length != control.find('option').length) {
            // All options were selected, user deselected one option
            // => unselect 'All' option
            control.selectpicker('val', valuesOf(control.find('option:selected[value!=All]')));
            allOptionIsSelected = false;
        } else if (!allOptionIsSelected && control.val().length == control.find('option').length - 1) {
            // Not all options were selected, user selected all options except 'All' option
            // => select 'All' option too
            control.selectpicker('val', valuesOf(control.find('option')));
            allOptionIsSelected = true;
        }
    }
    control.data('allOptionIsSelected', allOptionIsSelected);
}

$('#divRatings').selectpicker().change(function(){toggleSelectAll($(this));}).trigger('change');

http://jsfiddle.net/bu5vjdk6/4/


Обновлен код
http://jsfiddle.net/surajkm33/tsomyckj/

person glyuck    schedule 23.01.2015
comment
Большое спасибо, как по мне, вы проделали большую работу) Можно убрать .selectpicker() из последней строки? Пробую в jsFiddle, вроде работает. Потому что в моем проекте .selectpicker() в undefined, даже если библиотека загружена - person demo; 23.01.2015
comment
Да, удали. Я добавил его, чтобы гарантировать, что '.selectpicker()' применяется к выбору, прежде чем я вызову .trigger('change') для него (который вызывается для актуализации начального состояния выбора). - person glyuck; 23.01.2015
comment
Можете ли вы сказать, что может вызвать эту проблему: TypeError: control.selectpicker is not a function (control.selectpicker('val', []);) Потому что я не могу понять, что это такое. Я проверяю, включаю ли я все библиотеки, такие как jquery bootstrap и bootstrap-select - person demo; 23.01.2015
comment
Попробуйте обернуть свой код $(function() { // code here });. Или удалите .trigger из последней строки моего скрипта. - person glyuck; 23.01.2015
comment
@glyuck, когда я удаляю selectpicker() и trigger(), я не могу получить доступ к функции переключения - person demo; 23.01.2015
comment
Хотел бы я проголосовать в 10 раз больше. Ваш ответ хорошо объяснен, элегантен и помогает. Большое спасибо. - person Luis Milanese; 15.03.2017

Используйте атрибут data-actions-box="true", чтобы выбрать все и отменить выбор всего. Попробуйте этот код

<select id="divRatings" class="selectpicker" multiple title='Choose one of the following...' data-size="5" data-selected-text-format="count>2" data-actions-box="true">
            <option value="All" selected="selected">All Ratings</option>
            <option value="EC">EC (Early Childhood)</option>
            <option value="E">E (Everyone)</option>
            <option value="E10+">E10+ (Everyone 10+)</option>
            <option value="T">T (Teen)</option>
            <option value="M">M (Mature)</option>
            <option value="AO">AO (Adults Only)</option>
        </select>

Посетите [https://silviomoreto.github.io/bootstrap-select/options/][1]

[1]: https://silviomoreto.github.io/bootstrap-select/options/ Узнать больше

Надеюсь, эта помощь...

person M. K Hossain    schedule 27.03.2017
comment
Просто и полезно... - person Mohammad Saberi; 31.03.2021

Попробуйте это выберите Все

$('#idSelect option').attr("selected","selected");
$('#idSelect').selectpicker('refresh');

Снять все

$('#idSelect option').attr("selected",false);
$('#idSelect').selectpicker('refresh');

для меня это сработало.

person Gleny    schedule 26.11.2015

На него был дан ответ, но я нашел лучший способ сделать это.

Просто добавьте data-actions-box="true" в качестве атрибутов тега select.

Eg.

<label>Select/deselect all</label>
<select class="selectpicker form-control" data-style="btn-outline-warning" multiple data-actions-box="true">
    <optgroup label="Condiments">
        <option>Mustard</option>
        <option>Ketchup</option>
        <option>Relish</option>
    </optgroup>
    <optgroup label="Breads">
        <option>Plain</option>
        <option>Steamed</option>
        <option>Toasted</option>
    </optgroup>
</select>

person Samuel Bié    schedule 29.05.2020

Вы можете использовать мои функции:

сначала измените свой код

<option value="All" selected="selected">All Ratings</option>

to

<option value="All" id="target" selected="selected">All Ratings</option>

и второй добавить между вашими <script> тегами

$( "#target" ).toggle(function() {
  selectAll($( "#divRatings" ))
}, function() {
  selectClear($( "#divRatings" ))
});

function selectAll(element){//Select All Function
    element.prop('selected', true);
    element.selectpicker('refresh');
}
function selectClear(element){//Clear All Function
    element.prop('selected', false);
    element.selectpicker('refresh');
}
person Ferhat KOÇER    schedule 29.04.2017

Я столкнулся с этим вопросом, когда искал быстрое решение для включения/отключения всех опций в selectpicker <select>, и в итоге я разработал свой собственный стиль с одной строкой, который работает как для включенного, так и для выключенного состояния. :

Итак, для заданного select#my-select:

HTML

<div>
    <input type="checkbox" id="select_all" data-id-select="my-select">
    <label for="select_all">Toggle all</label>
</div>

JS/jQuery

$('#select_all').on('click', function() {
    $('#' + $(this).data('id-select')).find('option').prop('selected', $(this).is(':checked')).parent('select').selectpicker('refresh');
});
person D4V1D    schedule 07.02.2019

Я начал с ответа @glyuck, но немного изменил его. Я не хотел, чтобы элемент «Все» был выбран, а затем при начальной загрузке отображалось «Выбрано N элементов», в котором один из них был элементом «Все». Так что в основном для меня этот элемент «никогда не будет выбирать», это более или менее просто «кнопка» для переключения состояний.

Моя разметка будет выглядеть так:

<select size="4" multiple="multiple" class="form-control selectpicker show-tick select-all" data-selected-text-format="count > 2">
    <option value="[all]" class="select-all">All Items</option>
    <option value="" data-divider="true"></option>
    <option value="0">Members Selected</option>
    <option value="1">Separated Members Selected</option>
    <option value="2">Request Approval</option>
    <option value="3">Approved</option>
    <option value="4">Rejected</option>
</select>

Затем код, чтобы заставить его работать так, как я хотел, был:

$('.selectpicker.select-all').on('change', function () {
    var selectPicker = $(this);
    var selectAllOption = selectPicker.find('option.select-all');
    var checkedAll = selectAllOption.prop('selected');
    var optionValues = selectPicker.find('option[value!="[all]"][data-divider!="true"]');

    if (checkedAll) {
        // Process 'all/none' checking
        var allChecked = selectAllOption.data("all") || false;

        if (!allChecked) {
            optionValues.prop('selected', true).parent().selectpicker('refresh');
            selectAllOption.data("all", true);
        }
        else {
            optionValues.prop('selected', false).parent().selectpicker('refresh');
            selectAllOption.data("all", false);
        }

        selectAllOption.prop('selected', false).parent().selectpicker('refresh');
    }
    else {
        // Clicked another item, determine if all selected
        var allSelected = optionValues.filter(":selected").length == optionValues.length;
        selectAllOption.data("all", allSelected);
    }
}).trigger('change');

Спасибо @glyuck за вдохновение.

Скрипт: http://jsfiddle.net/3Lr4jsz0/

person Terry    schedule 01.06.2019

person    schedule
comment
логичный ответ, но все равно не работает jsfiddle.net/bu5vjdk6/1 Не знаю, почему - person demo; 23.01.2015