Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Toggling hover on dropdown between mobile and desktop

I have some simple JS that removes or adds html based on the width of the browser. If it's in mobile then the attribute data-hover should be removed. If the width is in desktop, then the attribute should be added.

So far this works great, but the problem is Bootstrap doesn't recognize that data-hover has been removed. The dropdown still closes when the user's mouse leaves the dropdown. To be clear, I want the dropdown to stay open when the user's mouse leaves the dropdown when the window browser width's is below 768px.

What's wrong and how do I fix this?

JS

$(document).ready(function () {
  $( window ).resize(function() {
    if ($( window ).width() < 768) {
      $('.dropdown-toggle').removeAttr('data-hover');
    } else {
      $('.dropdown-toggle').attr('data-hover', 'dropdown');
    }
  });
});

HTML

<a class="dropdown-toggle" data-hover="dropdown" data-toggle="dropdown" role="menu" aria-expanded="false" href="/courses">
  Courses               
</a>

<ul class="dropdown-menu courses-dropdown">
  <li>hello</li>                            
</ul>
like image 464
thank_you Avatar asked Jun 21 '16 16:06

thank_you


2 Answers

Instead of removing the attribute completely, you could reassign it to nothing like so:

$('.dropdown-toggle').attr('data-hover', '');

If there is no value assigned to the attribute, it shouldn't do anything.

like image 120
BDD Avatar answered Nov 18 '22 09:11

BDD


NOTE: The solution provided by BDD with regards to setting data-hover to an empty string will work if you are using the responsibly built dropdown hover plugin. However, the OP was using a rather poorly built dropdown hover plugin and this answer serves to duct tape the problems with that plugin.

It appears that the data-hover is not part of bootstraps dropdown but rather some guys extension to bootstrap. Unfortunate for you and the community at large the guy didn't provide a way to destroy his plugin. It always amazes me how plugin authors never provide a way to tear down their plugins as this is a severe cause of memory leaks and is is just poor programming in general.</rant>

In order to make things right, you are going to have to manually unbind and rebind the events yourself. Again, unfortunate for you and the community, he didn't namespace the hover events - which, again, is real irresponsible plugin development (crying inside). Since we are going to be doing all this work that the plugin author should have done, we might as well extend the plugin and make it appear as though the author knew what he was doing. Please note that if any other functionality on the page is adding hover events to the dropdowns, that functionality is going to break (this is because the author didn't namespace his events).

$.fn.dropdownHover.disableAll = function () {
    $('[data-hover="dropdown"]').each(function() {
        $(this).off('hover').parent().off('hover').find('.dropdown-submenu').off('hover');
    });
});

$.fn.dropdownHover.enableAll = function () {
    $('[data-hover="dropdown"]').dropdownHover();
});

and now inside your resize event you should do something like this:

var $window = $( window );
$(document).ready(function () {
  $window.resize(function() {
    if ($window.width() < 768) {
      $.fn.dropdownHover.disableAll();
    } else {
      $.fn.dropdownHover.enableAll();
    }
  });
});

You may have to play around with the above code since I can't really test this. Let me know if it works or not. And since we've gone to all this work, for the love of everything good in this world will you please call the disableAll function if you are using this on a single page application and the current page changes. This is how you can prevent memory leaks. Thanks.

like image 22
Ryan Wheale Avatar answered Nov 18 '22 11:11

Ryan Wheale