3

My question is a variation on this other question

Instead of a button I want to use an input field to toggle a dropdown. The issue is that without extra code the dropdown does not open when tabbing into the input. That can be captured by the focusin event.

I found a working solution (shown below), but it is a bit quirky in that it opens-closes-opens the dropdown on click although I don't see a visible flashing.

Now, clicking into the edit control first triggers the focusin event followed by the click event. As in the other question I tried stopping bootstrap from opening the dropdown on click by calling e.stopPropagation(), e.preventDefault(), and returning false from the event handler; nothing works. The effect is that the dropdown quickly flashes and immediately disappears. As can be seen from the #msg text, a click triggers first a focusin, then a click event.

Any suggestions?

One idea was to trigger click during the focusin event, but now that means on a physical click the click event gets fired twice and the dropdown flashes. I'm also not sure what other adverse side effects that could have.

HTML (simplified for clarity):

<div class="ml-4">
  <input type="text" class="form-control" id="Medium" name="Medium" placeholder="Medium" value="">
</div>
<div class="ml-4 dropdown">
  <input type="text" class="form-control" id="Material" name="Material" placeholder="Material" value="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  <div class="dropdown-menu" aria-labelledby="Material">
    <button class="dropdown-item" type="button">Action</button>
    <button class="dropdown-item" type="button">Another action</button>
    <button class="dropdown-item" type="button">Something else here</button>
  </div>
</div>
<div class="ml-4">
 <div style="height:200px;"></div>
 <input type="text" class="form-control" id="Dummy" name="Dummy" placeholder="Dummy" value="">
 <p id="msg">S</p>
</div>

JS working (the code dealing with #msg is for debugging):

$("#Material").focusin(function(e) {
 $("#msg").text($("#msg").text() + '-i');
 $(this).dropdown('toggle');
});
$("#Material").click(function(e) {
 $("#msg").text($("#msg").text() + '-c');
 // when removing the following line, neither e.stopPropagation(), e.preventDefault(), nor returning false helps
 $(this).dropdown('toggle');
});
$("#Material").focusout(function(e) {
 $("#msg").text($("#msg").text() + '-o');
});
Rudiger W.
  • 796
  • 7
  • 13

1 Answers1

1

I may have found a solution: wrap the input in a div, trigger the dropdown on the input's parent, and prevent the click event from propagating.

HTML:

<input type="text" class="form-control" id="Material" name="Material" placeholder="Material" value="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">

becomes

<div data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
   <input type="text" class="form-control" id="Material" name="Material" placeholder="Material" value="">
</div>

JS: (changed parts only)

$("#Material").focusin(function(e) {
 $("#msg").text($("#msg").text() + '-i');
 $(this).parent().dropdown('toggle');
});
$("#Material").click(function(e) {
 e.stopPropagation();
 $("#msg").text($("#msg").text() + '-c');
});

This solution seems to work fine.

Rudiger W.
  • 796
  • 7
  • 13