简体   繁体   中英

jQuery UI: How to check whether another instance of widget is opened?

I've created custom widget by extending jQuery UI's Menu . It's basically needed to work with <select> HTML element like ui.selectmenu does, but display options in submenus:

$.widget("market.myMenu",$.ui.menu, {
// ...
_attachEvents: function(){
    var self = this;
    // menu is initially hidden
    self.menuWrapper.hide();
    self.button.on('click', function(){
        if (self.originalSelect.is(':disabled')) {
            self.disable();
        } else {                
            self.menuWrapper.toggle();
        }
        return false;
    });

    $(document).on('click', function(){
        self.menuWrapper.hide();
    });             
},
//...
  }
}

The problem arise when this widget attached to multiple elements like:

someSelect.myMenu();
//...
anotherSelect.myMenu();

The problem is listed in the title and you can see it in _attachEvents() method:

  1. when user clicks on someSelect it opens as should
  2. then user clicks on anotherSelect it also opens
  3. someSelect after step 2 should be closed, but it's not.

So how to check for such a case and fix this issue ?

EDIT:

  1. this.originalSelect is <select> HTML element
  2. this.button is div element. on which selected option text is displayed (basically same thing as ui.selectmenu does);

You can use a class to keep track of the state of your menus and use it to target instances that are opened. Something like this for example:

_attachEvents: function(){
    var self = this;
    // menu is initially hidden
    self.menuWrapper.hide();
    self.button.on('click', function(){
        if (self.originalSelect.is(':disabled')) {
            self.disable();
        } else {
            // before you open a menu, you close the opened ones
            $('menu-opened').each(function(){
                $(this).myMenu('instance').hideWrapper();
            });
            self.menuWrapper.toggleClass('menu-opened');                
            self.menuWrapper.toggle();
        }
        return false;
    });

    $(document).on('click', function(){
        self.menuWrapper.hide();
    });             
},

hideWrapper: function(){
    var self = this;
    self.menuWrapper.hide();
    self.menuWrapper.removeClass('menu-opened');
}

I've found solution. It's based upon Julien Grégoire proposal to use css marker class.

What I'm doing is adding class ui-mymenu-wrap to self.menuWrapper element. So all widgets have those identifier. The next thing I do is after clicking on one widget I'm closing all others menus and then open/close widget on which click was made.

_attachEvents: function(){
    var self = this;
    // menu is initially hidden
    self.menuWrapper.hide();
    self.button.on('click', function(event){
        if (self.originalSelect.is(':disabled')) {
            self.disable();
        } else {
            // hide all opened menus
            $('.ui-mymenu-wrap').not(self.menuWrapper).hide();
            self.menuWrapper.toggle();                  
        }
        return false;
    });

    $(document).on('click', function(){
        self.menuWrapper.hide();
    });             
},

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM