Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Javascript select all on dropdown with checkbox and search

I have a checkbox dropdown that has a search and select all.
They both work great, the thing is when i search, i would like the select all to only select all the displayed checkboxes, right now after a search and i click select all it still selects every box.

Here is my html

<div id="dropdownSearch" class="hidden bg-white rounded-lg shadow w-60" style="z-index: 999;">
<div class="p-3">
    <label for="input-group-search" class="sr-only">Search</label>
    <div class="relative">
        <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
            <svg class="w-5 h-5 text-gray-500 dark:text-gray-400" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"></path></svg>
        </div>
        <input type="text" id="myInput" onkeyup="filterFunction()" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5 " placeholder="Search user">
    </div>
</div>
    <div class="ml-4 flex items-center p-1 rounded hover:bg-gray-100">
        <input id="checkbox-item-14" onchange="selectAll()" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500">
        <label for="checkbox-item-14" id="select_all" class="w-full ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300">Select All</label>
    </div>
<ul id="getMerchant" class="h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownSearchButton">
    @foreach($mids as $mid)
        <li>
            <div id="myDropdown" class="flex items-center p-2 rounded hover:bg-gray-100 ">
                <input id="merchant" name="merchant[]" type="checkbox" value="{{$mid->mid_id}}" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 ">
                <label for="merchant-checkbox" id="merchant_name" class="w-full ml-2 text-sm font-medium text-gray-900 rounded ">{{$mid->mid_name}}</label>
            </div>
        </li>
    @endforeach
</ul>

Here is my Javascript

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<script>
    function filterFunction() {
        var input, filter, ul, li, a, i;
        input = document.getElementById("myInput");
        filter = input.value.toUpperCase();
        console.log(filter);
        div = document.getElementById("getMerchant");
        a = div.getElementsByTagName("li");
        for (i = 0; i < a.length; i++) {
            txtValue = a[i].textContent || a[i].innerText;
            if (txtValue.toUpperCase().indexOf(filter) > -1) {
                a[i].style.display = "";
            } else {
                a[i].style.display = "none";
            }
        }
    }

    function selectAll(){
        if($('#checkbox-item-14').is(':checked')){
            var ele = document.querySelectorAll("input[type=checkbox]");
            for(var i=0;i<ele.length;i++){
                ele[i].checked = true;
            }
        }else{
            var ele = document.querySelectorAll("input[type=checkbox]");
            for(var i=0;i<ele.length;i++){
                ele[i].checked = false;
            }
        }
    }
</script>

>Solution :

To keep the Select All option when searching, consider starting the for loop from index 1, so that it skips the first <li>, the <li> that contains the Select All option:

for (i = 1; i < a.length; i++) {

For the Select All to only work for the currently filtered items, first, use the hidden class instead of using the style attribute. This will make it easier to not select the hidden items:

a[i].classList.toggle('hidden', txtValue.toUpperCase().indexOf(filter) === -1);

Then when toggling the Select All checkbox, select checkbox <input> elements that are not hidden:

var ele = document.querySelectorAll("li:not(.hidden) > div > input[type=checkbox]");

Putting it all together:

function filterFunction() {
  var input, filter, ul, li, a, i;
  input = document.getElementById("myInput");
  filter = input.value.toUpperCase();
  console.log(filter);
  div = document.getElementById("getMerchant");
  a = div.getElementsByTagName("li");
  for (i = 1; i < a.length; i++) {
    txtValue = a[i].textContent || a[i].innerText;
    a[i].classList.toggle('hidden', txtValue.toUpperCase().indexOf(filter) === -1);
  }
}

function selectAll() {
  var ele = document.querySelectorAll("li:not(.hidden) > div > input[type=checkbox]");
  var checked = $('#checkbox-item-14').is(':checked');
  for (var i = 0; i < ele.length; i++) {
    ele[i].checked = checked;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min.js" integrity="sha512-3gJwYpMe3QewGELv8k/BX9vcqhryRdzRMxVfq6ngyWXwo03GFEzjsUm8Q7RZcHPHksttq7/GFoxjCVUjkjvPdw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com"></script>

<div id="dropdownSearch" class="bg-white rounded-lg shadow w-60" style="z-index: 999;">
  <div class="p-3">
    <label for="input-group-search" class="sr-only">Search</label>
    <div class="relative">
      <div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
        <svg class="w-5 h-5 text-gray-500 dark:text-gray-400" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd"></path></svg>
      </div>
      <input type="text" id="myInput" onkeyup="filterFunction()" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full pl-10 p-2.5 " placeholder="Search user">
    </div>
  </div>
  <ul id="getMerchant" class="h-48 px-3 pb-3 overflow-y-auto text-sm text-gray-700 dark:text-gray-200" aria-labelledby="dropdownSearchButton">
    <li>
      <div class="flex items-center p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-600">
        <input id="checkbox-item-14" onchange="selectAll()" type="checkbox" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500">
        <label for="checkbox-item-14" id="select_all" class="w-full ml-2 text-sm font-medium text-gray-900 rounded dark:text-gray-300">Select All</label>
      </div>
    </li>
    <li>
      <div id="myDropdown" class="flex items-center p-2 rounded hover:bg-gray-100 ">
        <input id="merchant" name="merchant[]" type="checkbox" value="foo" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 ">
        <label for="merchant-checkbox" id="merchant_name" class="w-full ml-2 text-sm font-medium text-gray-900 rounded ">foo</label>
      </div>
    </li>
    <li>
      <div id="myDropdown" class="flex items-center p-2 rounded hover:bg-gray-100 ">
        <input id="merchant" name="merchant[]" type="checkbox" value="bar" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 ">
        <label for="merchant-checkbox" id="merchant_name" class="w-full ml-2 text-sm font-medium text-gray-900 rounded ">bar</label>
      </div>
    </li>
    <li>
      <div id="myDropdown" class="flex items-center p-2 rounded hover:bg-gray-100 ">
        <input id="merchant" name="merchant[]" type="checkbox" value="baz" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 ">
        <label for="merchant-checkbox" id="merchant_name" class="w-full ml-2 text-sm font-medium text-gray-900 rounded ">baz</label>
      </div>
    </li>
  </ul>
</div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading