Thursday, May 24, 2012

Creating drop menu component by using jqueryui dialog and menu components 

I like jquery and I like JqueryUI. Recently I needed an popup menu appears on button (or buttons) click.
The easiest way I found is to use from what I already have in jqueryui - dialog and menu components.

All jqueryui components are built with jqueryui widget factory and have to say I love it :-). You should really get familiar with widget factory and you will find how easy is to build custom/composite components with it.

Please not that I am using jquery 1.9 which is still in beta phase but I am satisfied with its stability.

Features requested


  1. One content container should open by multiple buttons just bellow button triggered it
  2. Menu should

The code

(function ($) {
    $.widget("sauti.dropmenu", {
        options: { // we overwrite defaults from dialog component
            autoResize: true,
            closeOnEscape: true,
            closeOnSelect: true,
            minWidth: 250,
            minHeight: 200,
            height: 'auto',
            resize: 'auto',
            autoOpen: false,
            resizable: false,
            modal: false
        },
        _create: function () {
            var self = this;
       
        self.element
                .bind('click', function (e) {
                    e.stopPropagation(); // we don't need to propagate click event on our dialog
                })
                .dialog(self.options) // now our element is dialog
                .bind('dialogopen', function (e, ui) {
                    $(document.body).one('click', function () {  // when dialog is open click everywhere on document but our element or trigger should close dialog
                        self.close();
                    });
                    self._trigger('open', e, ui);  // trigger open event
                })
                .bind('dialogclose', function (e, ui) {
                    self._trigger('close', e, ui); // trigger close event
                })
                .parent().addClass('ui-dropdown') // since dialog wraps this.element into container we put our "ui-dropdown" class on element parent
                .find('ul').menu({  // if there is ul make menu with it
                    select: function (e, ui) {
                        self._trigger('select', e, ui);
                        if (self.options.closeOnSelect === true)  // if set to true dialog will close when user selects item from menu
                            self.close();
                    }
                });
        },
        open: function (event) {
            var self = this,
                trigger = $(event.currentTarget); // this is the element triggered action

            // we don't want to propagate event to parent
            event.stopPropagation();

            if (trigger && !$.isEmptyObject(trigger)) { // I like to make sure :-)
            // calculate position  
            var x = trigger.position().left,
                    y = trigger.position().top - $(document).scrollTop() + trigger.outerHeight();
         
          // set this position to our dialog and open it
                self.element
                    .dialog('option', 'position', [x, y])
                    .dialog('open');
            }
            else
                self.element.dialog('open'); // this means user called open method by code
        },
        close: function (event) {
            var self = this;
            self.element.dialog('close');
        }
    });
})(jQuery);

Usage would be
Html
<div id="mymenu">
  <ul><a>Hello</a><ul>
  <ul><a>My</a><ul>
  <ul><a>World</a><ul>
</div>

Javascript
// Create menu
var dm = $("#mymenu").dropmenu();


// Open by any button
$(".myButtons").click(function(e) {
   dm.dropmenu("open", e); // e is very important
})

This is my first blog post ever. I hope that this is just the begin.

No comments:

Post a Comment