Showing posts with label jquery. Show all posts
Showing posts with label jquery. Show all posts

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.