I have many (dynamic) input with each having its own dropdown
I want to keep the dropdown popup in focus when the current input is active/being typed , now the issue is my dropdown menu closes when I type in textbox
I cannot use ID selector and hard code since the number of dropdowns are dynamic.
I have tried with
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA 058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." id="myInput" >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5 76PVCmYl" crossorigin="anonymous"></script>
<script>
$(function(){
$('.dropdown-item').click(function(e){
var value = $(this).data('value');
var textElement = $(this).parent().parent().prev()
textElement = textElement.val(textElement.val() value);
event.preventDefault();
event.stopPropagation();
textElement.focus()
});
});
$(".search").keyup(function(){
var input, filter, ul, li, a, i;
input = $(this).get(0);
filter = input.value.toUpperCase();
div = $(this).parent().get(0);
a = div.getElementsByTagName("a");
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() {
var disable = false;
$('.dropdown-toggle').on('mousedown touchstart', function() {
disable = true;
console.log("inside1")
})
.on('focus', function() {
if (!disable) {
$(this).dropdown('toggle'); console.log("inside2")
}
})
.on('mouseup touchend',function() {
disable = false;console.log("inside3")
})
})()
</script>
</body>
</html>
CodePudding user response:
$(document).ready(() => {
$(".input-group > input")
.on("focus", (e) => {
let inputEl = e.currentTarget;
let dropdownEl = inputEl.parentElement.querySelector(".dropdown-menu");
$(dropdownEl).show();
})
.on("blur", (e) => {
// If click outside the input, check for condition to hide the dropdown
let inputEl = e.currentTarget;
let dropdownEl = inputEl.parentElement.querySelector(".dropdown-menu");
let dropdownSearchEl = dropdownEl.querySelector('.search');
if (e.relatedTarget == dropdownSearchEl) {
// Check if the target is the input insdie dropdown, then return to prevent the dropdown hiding
return;
}
$(dropdownEl).hide();
})
.on('keyup', (e) => {
let inputEl = e.currentTarget;
let dropdownEl = inputEl.parentElement.querySelector(".dropdown-menu");
let dropdownSearchEl = dropdownEl.querySelector('.search');
// Un-comment here if you want to set the value of the dropdown input as the value of the actual input
// dropdownSearchEl.value = inputEl.value;
});
$(".search")
.on("blur", (e) => {
// When click outside the dropdown search input, hide the dropdown
let dropdownInputEl = e.currentTarget;
let dropdownEl = dropdownInputEl.parentElement;
$(dropdownEl).hide();
})
.on("keyup", function() {
var input, filter, ul, li, a, i;
input = $(this).get(0);
filter = input.value.toUpperCase();
div = $(this).parent().get(0);
a = div.getElementsByTagName("a");
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";
}
}
});
});
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA 058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." id="myInput" >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<div >
<input type="text" aria-label="Text input with segmented dropdown button">
<div >
<button type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
</button>
<div >
<input type="text" placeholder="Search.." >
<a data-value="{{Action}}" href="#">Action</a>
<a data-value="{{Another action}}" href="#">Another action</a>
<a data-value="{{Something else here}}" href="#">Something else here</a>
<div role="separator" ></div>
<a data-value="{{Separated lin}}" href="#">Separated link</a>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-ApNbgh9B Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5 76PVCmYl" crossorigin="anonymous"></script>
</script>
</body>
</html>
Since you are using Bootstrap dropdown, you can use its Popover
methods to toggle show/hide the dropdown Bootstrap Popover.
The steps I do to achieve what you want:
- Assign event
focus
andblur
on theinput
to show/hide the dropdown. Inside theblur
event, I check for the condition if the user click on the dropdown's input, then still keep the dropdown opening - Assign the event
blur
on the dropdown input to hide the dropdown
Ps: Using the jQuery event
you can get the related DOM element, to experiment a little bit further, you can log the event then use the Devtool to look for the element you want to get. As you can see, in the script, I use event.currentTarget
to get the element that the user click on. That's solve the problem.