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