#html #jquery #css #twitter-bootstrap
#HTML #jquery #css #twitter-bootstrap
Вопрос:
У меня есть раскрывающийся список начальной загрузки, в котором есть флажки в параметрах. Когда я выбираю один флажок, текст флажка отображается в раскрывающейся кнопке.
Проблема в том, что он работает не так, как я хочу, когда установлено несколько флажков. Когда я устанавливаю два флажка, отображается текст последнего нажатого флажка. Этого не должно быть, вместо текста флажка я хочу, чтобы в раскрывающейся кнопке отображалось «Выбранные 2 элемента».
Как я могу решить эту проблему?
$(".dropdown-menu a").click(function() {
var selText = $(this).text();
$(this).parents('.btn-group').find('.dropdown-toggle').html(selText);
});
// checbox
$('#checkall').change(function() {
$('.cb-element').prop('checked', this.checked);
});
$('.cb-element').change(function() {
if ($('.cb-element:checked').length == $('.cb-element').length) {
$('#checkall').prop('checked', true);
} else {
$('#checkall').prop('checked', false);
}
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="btn-group ">
<button class="btn btn-secondary dropdown-toggle text-center" type="button" data-toggle="dropdown">
Dropdown button
</button>
<div class="dropdown-menu">
<a class="dropdown-item"><input type="checkbox" name="all" class="mr-2" id="checkall">Check All</br>
</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 1</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 2</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 3</a>
</div>
</div>
Ответ №1:
На самом деле вы можете сделать это очень легко в коде, который у вас уже есть — вам просто нужно проверить количество выбранных параметров, прежде чем устанавливать ярлык:
- В этой строке будет указано количество выбранных флажков:
numSelected = $(this).parent(".dropdown-menu").find('.cb-element:checked').length;
- Теперь все, что вам нужно сделать, это проверить, так ли это
> 1
, и установить кнопку в:
selText = numSelected " selected";
Вот и все! (Не забывайте, что вам также нужно проверить, был ли снят текущий флажок — в настоящее время вы этого не делаете).
Показать ярлык «Все выбранные»:
Если вы хотите пофантазировать, вы также можете посмотреть, установлены ли все флажки, и вместо этого отобразить «все выбранные», или, если выбрано значение 1, затем показать метку этого.
totalNumOptions = $(".dropdown-menu .cb-element").length;
$(".dropdown-menu a").change(function() {
// get selected options
selected = $(this).parent(".dropdown-menu").find('.cb-element:checked');
if (selected.length == totalNumOptions || $("input#checkall:checked").length == 1)
// ALL options are selected, of "All checked" is checked
selText = "All selected";
else if (selected.length == 1)
// show text of the SELECTED option (NOTE: not clicked option!)
selText = $(selected[0]).parent().text();
else
// show number of selected options
selText = selected.length " selected";
$(this).parents('.btn-group').find('.dropdown-toggle').html(selText);
});
Рабочий пример:
// Get the total number of options so we can see if all are checked
// do this outside of handler so we only do it once
var totalNumOptions = $(".dropdown-menu .cb-element").length;
$(".dropdown-menu a").change(function() {
// get number of selected options
selected = $(this).parent(".dropdown-menu").find('.cb-element:checked');
if (selected.length == totalNumOptions ||
$(this).find("input#checkall:checked").length == 1)
// ALL options are selected
selText = "All selected";
else if (selected.length == 1)
//only 1 selected so show the selected option
selText = $(selected[0]).parent().text();
else
// show number of selected options
selText = selected.length " selected";
$(this).parents('.btn-group').find('.dropdown-toggle').html(selText);
});
// checbox
$('#checkall').change(function() {
$('.cb-element').prop('checked', this.checked);
});
$('.cb-element').change(function() {
if ($('.cb-element:checked').length == $('.cb-element').length) {
$('#checkall').prop('checked', true);
} else {
$('#checkall').prop('checked', false);
}
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="btn-group ">
<button class="btn btn-secondary dropdown-toggle text-center" type="button" data-toggle="dropdown">
Dropdown button
</button>
<div class="dropdown-menu">
<a class="dropdown-item"><input type="checkbox" name="all" class="mr-2" id="checkall">Check All</br>
</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 1</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 2</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 3</a>
</div>
</div>
Комментарии:
1. @Akash Рад помочь! Обратите внимание, я внес небольшую корректировку в свой ответ — вы не проверяли, был ли выбран флажок, на который нажимали (возможно, он не был выбран!), Поэтому проверьте новый обработчик щелчков — он просто получает текст
selected
флажка, а неclicked
один!
Ответ №2:
Вы можете попробовать это, я внес некоторые изменения
$(".dropdown-menu a").click(function() {
var selText = $(this).text();
$(this).parents('.btn-group').find('.dropdown-toggle').html("selected " $('.cb-element:checked').length " item");
});
// checbox
$('#checkall').change(function() {
var dropDown = $(this).parents('.btn-group').find('.dropdown-toggle');
$('.cb-element').prop('checked', this.checked);
if (!$('.cb-element:checked').length)
dropDown.html("Dropdown button");
else
dropDown.html("selected " $('.cb-element:checked').length " item");
});
$('.cb-element').change(function() {
if ($('.cb-element:checked').length == $('.cb-element').length) {
$('#checkall').prop('checked', true);
} else {
$('#checkall').prop('checked', false);
}
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="btn-group ">
<button class="btn btn-secondary dropdown-toggle text-center" type="button" data-toggle="dropdown">
Dropdown button
</button>
<div class="dropdown-menu">
<a class="dropdown-item"><input type="checkbox" name="all" class="mr-2" id="checkall">Check All</br>
</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 1</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 2</a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"> Checkbox 3</a>
</div>
</div>
Ответ №3:
Попробуйте это вместо,
Прежде всего, добавьте ярлык с for
атрибутом, чтобы щелкнуть событие в ярлыке, чтобы установить флажок. вот так
<a class="dropdown-item">
<input type="checkbox" name="all" class="mr-2" id="checkall">
<label for="checkall">Check All</label>
</a>
Затем проверьте, сколько проверили выпадающий элемент. Автор:
var len = $('.dropdown-menu .dropdown-item input:checked').length;
если кнопка checkall нажата, то с помощью
if($('#checkall:checked').length){
len= "3";
}
Наконец, кнопка добавления в раскрывающийся список
$(this).parents('.btn-group').find('.dropdown-toggle').html("Selected " len " item");
$(".btn-group .btn.btn-secondary").click(function(){
$('.dropdown-menu .dropdown-item input').change(function () {
var len=$('.dropdown-menu .dropdown-item input:checked').length;
// to get number of checked checkbox
if($('#checkall:checked').length | len == 3){
len= "All"; // if checked all check box to value to '3'
}
$(this).parents('.btn-group').find('.dropdown-toggle').html("Selected " len " item");
// to assign value to dropdown button
});
});
// for checkall
$('#checkall').change(function () {
$('.cb-element').prop('checked',this.checked);
});
$('.cb-element').change(function () {
if ($('.cb-element:checked').length == $('.cb-element').length){
$('#checkall').prop('checked',true);
}
else {
$('#checkall').prop('checked',false);
}
});
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="btn-group">
<button class="btn btn-secondary dropdown-toggle text-center" type="button" data-toggle="dropdown">Dropdown button</button>
<div class="dropdown-menu">
<a class="dropdown-item">
<input type="checkbox" name="all" class="mr-2" id="checkall">
<label for="checkall">Check All</label>
</a>
<a class="dropdown-item">
<input type="checkbox" id="check1" class="cb-element mr-2">
<label for="check1">Checkbox 1</label>
</a>
<a class="dropdown-item">
<input type="checkbox" id="check2" class="cb-element mr-2">
<label for="check2">Checkbox 2</label>
</a>
<a class="dropdown-item">
<input type="checkbox" id="check3" class="cb-element mr-2">
<label for="check3">Checkbox 3</label>
</a>
</div>
</div>
Комментарии:
1. Добавление нового обработчика событий внутри каждого
$(".dropdown-menu a").click
кажется здесь плохой идеей.2. @MarkSchultheiss Спасибо :). Обновлен ответ.
3. ну, нет, это все равно добавляет новый обработчик событий «изменить» при каждом нажатии
$(".btn-group .btn.btn-secondary").click(function(){ $('.dropdown-menu .dropdown-item input').change(function () {
Ответ №4:
Я нахожу этот шаблон checkbox / check all интересным тем, что вы должны обработать щелчок «все» и «нормально» и установить значения. Это также интересно, поскольку оно находится в «выпадающем» визуальном представлении, поэтому вы должны держать его открытым для лучшего взаимодействия с пользователем при выборе. Кроме того, у вас есть «пользовательские» метки для выпадающего меню, зависящие от того, что проверено. Все это интересный поведенческий комплекс.
Мне не нравится использовать глобальные переменные, которые могут быть возможным дубликатом другого кода, и я предпочитаю хранить вещи в пространстве имен — не причудливом и не экземпляре, но все же полезном по этим причинам.
Я привожу пример использования элемента «label» для текста раскрывающегося списка, а также свойства «data» для его хранения, чтобы у нас было продемонстрировано несколько вариантов.
Комментарии в строке, чтобы помочь с тем, что он делает.
Обратите внимание, что я использую CSS вместо строки <br />
для интервала, что также позволяет мне немного изменить его стиль (зеленое подчеркивание) и выбрать, сколько полей добавить к «проверить все»
// namespace to avoid globals
var myApp = myApp || {
checkBoxes: {},
originalText: "",
toggleText: "Checked ",
handleCheckboxEvents: function(event) {
// keep event from bubble to 'a' tag
event.stopImmediatePropagation()
let checkedOnes = myApp.checkBoxes.filter(':checked');
let checkCount = checkedOnes.length;
let checkedAll = checkCount === myApp.checkBoxes.length;
// use if single checked for label
let label = checkedOnes.first()
.closest('.dropdown-item')
.find('.check-label').html();
// labels can come from data also like this example
let checkallLabel = $('.checkall-item').data('all');
// non checked use original
let selText = checkCount === 0 ?
myApp.originalText :
// one checked use its label
checkCount === 1 ? label :
// checked all?
checkedAll ? checkallLabel :
// more than one - use number checked
myApp.toggleText checkCount;
// set the text we determined
$(this).closest('.btn-group')
.find('.dropdown-toggle')
.html(selText);
$('#checkall').trigger('set-checkall', [{
source: 'checkbox'
}]);
},
handleLinkClick: function(event) {
// keep link from being followed
event.preventDefault();
// keep dropdown menu from closing
event.stopPropagation();
let cb = $(this).find('input[type="checkbox"]');
let isChecked = cb.prop("checked");
cb.prop("checked", !isChecked);
cb.trigger('change');
},
handleCheckAll: function(event, data) {
// use the source of the event to set it
if (data.source == 'checkall') {
// toggle to what it is not
$(this).prop('checked', !this.checked);
$('.cb-element').prop('checked', this.checked).trigger('change');
}
if (data.source === 'checkbox') {
// set depending on how many checked
$(this).prop('checked', myApp.checkBoxes.filter(':checked').length == myApp.checkBoxes.length);
}
},
// initialize and attach event handlers
init: function() {
this.checkBoxes = $('.cb-element');
this.originalText = $('.btn-secondary.dropdown-toggle').html();
// handle the checkbox click or change
$(".dropdown-menu").find('a.dropdown-item')
.on('click change', 'input[type="checkbox"]', this.handleCheckboxEvents);
$(".dropdown-menu").find('a.dropdown-item')
.on('click', this.handleLinkClick);
// handle the checkall change by its wrapper click
$('.checkall-item').on('click', function() {
event.stopPropagation();
$('#checkall').trigger('set-checkall', [{
source: 'checkall'
}]);
});
// use custom event so we can use multiple places, passing it data
$('#checkall').on('set-checkall', this.handleCheckAll);
}
};
myApp.init();
.checkall-item .check-label {
margin-bottom: 1em;
border-bottom: 1px green solid;
display: inline-block;
font-weight:bold;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
<div class="btn-group my-dropdown-group">
<button class="btn btn-secondary dropdown-toggle text-center" type="button" data-toggle="dropdown">Dropdown button</button>
<div class="dropdown-menu">
<a class="dropdown-item checkall-item" data-all="Checked All"><input type="checkbox" name="all" class="mr-2" id="checkall"><span class="check-label">Check All</span></a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"><span class="check-label">Checkbox Fun</span></a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"><span class="check-label">Checkbox Happy</span></a>
<a class="dropdown-item"><input type="checkbox" class="cb-element mr-2"><span class="check-label">Checkbox Now</span></a>
</div>
</div>