Как я могу показать выбранные элементы в ярлыке раскрывающегося списка начальной загрузки?

#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:

На самом деле вы можете сделать это очень легко в коде, который у вас уже есть — вам просто нужно проверить количество выбранных параметров, прежде чем устанавливать ярлык:

  1. В этой строке будет указано количество выбранных флажков:
 numSelected = $(this).parent(".dropdown-menu").find('.cb-element:checked').length;
  
  1. Теперь все, что вам нужно сделать, это проверить, так ли это > 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>