javascriptjquerybackbone.jsbootstrap-4backbone-views

Open bootstrap dropdown on input focus


I have an input that when clicked shows a bootstrap 4 dropdown BUT I need it to open when a user tabs to it as well for ADA accessibility.

If I use a focus event that uses $('#input-name).dropdown('toggle') it works fine, but when the input is clicked focus fires first which opens the dropdown and then the click event closes it.

I have tried e.preventDefault(); e.stopPropagation(); but neither help solve this issue.

events: {
  focus #healthPlanMenu": "openDropDown"
}


openDropDown: function (e) {

  if ($('#healthPlanMenu').find('.dropdown-menu:no(.show)')){
    $("#healthPlanMenu.dropdown-toggle").dropdown('toggle');
   }//fails

    $("#healthPlanMenu.dropdown-toggle").dropdown('toggle');//fails
    $( "#healthPlanMenu" ).click();//fails

  }

Solution

  • So ideally you'd probably solve this by having the focus event set the dropdown's state to open, that way if it gets "reopened" by the click event, no problem. However, as far as I can tell there is only a toggle option with the jQuery API; seems unnecessarily limiting...

    Given that, we can know if a click is coming after our focus event by using mousedown. So a somewhat hacky way to solve this problem is to disable our focus event if we know a click is coming.

    (function() {
    	var disable = false;
    	$('#healthPlanMenu.dropdown-toggle')
    		.on('mousedown touchstart', function() {
    			disable = true;
    		})
    		.on('focus', function() {
    			if (!disable) {
    				$(this).dropdown('toggle');
    			}
    		})
    		.on('mouseup touchend',function() {
    			disable = false;
    		})
    })()

    I don't know if the touchstart and touchend are necessary as most browsers probably fire mouse events on touch as well. But better safe than sorry.