(function($){ $.sfs = $.extend($.sfs, { contextMenu : { init : function(_opt) { $(function() { var $contextMenu = $(_opt.selector); var opt = $.extend ( {} ,$.sfs.contextMenu.events ,_opt ); // event handler for (e in $.sfs.contextMenu.events) { if(opt[e] && typeof opt[e] !== 'function') opt[e] = eval('('+opt[e]+')'); } // init if($contextMenu.get(0)) { $contextMenu .contextMenu(opt) .data('sfs', $.extend($contextMenu.data('sfs'), {contextMenu: opt})); } }); }, events : {open:null, close:null, position:null} // hover:null, select:null, } }); $.widget("ui.contextMenu", { // default options options: { event : 'click', toggle : true, position : 'auto', nested : false }, _create: function() { this.element.hide(); var $context = $(this.options.context); if ($context) $context.bind (this.options.event, $.proxy(this, '_open')); }, _calculatePosition : function () { var $menu = this.element; var $context = $.ui.contextMenu.activeContext; var c_pos = $context.position(); var m_pos = $menu.position(); var css_opt = { position: 'absolute', top : c_pos.top + $context.height(), left : c_pos.left }; css_opt.top += 'px'; css_opt.left += 'px'; $menu.css(css_opt); this._trigger('position', e, {context:$context}); return this; }, _open : function (e) { e.stopPropagation(); var $menu = this.element; var $context = $(e.currentTarget); if( $context.get(0) !== (($.ui.contextMenu.activeContext)? $.ui.contextMenu.activeContext.get(0) : null) || !$menu.is(':visible') ) { this.closeActiveMenu(e); $.ui.contextMenu.activeMenu = $menu; $.ui.contextMenu.activeContext = $context; this._calculatePosition(); $menu.show(); this._trigger('open', e, {context:$context}); } else { this.closeActiveMenu(e); } return false; }, adjust : function() { this._calculatePosition(); }, closeActiveMenu : function(e){ var $menu = $.ui.contextMenu.activeMenu; if ($menu && $menu.is(':visible')) { $.ui.contextMenu.activeMenu.hide(); this._trigger('close', e, {context:$.ui.contextMenu.activeContext}); } }, destroy: function() { $.Widget.prototype.destroy.apply(this, arguments); // default destroy // now do other stuff particular to this widget } }); $(document).click(function(){ var $menu = $.ui.contextMenu.activeMenu; if ($menu) $menu.contextMenu('closeActiveMenu'); }); $(window).resize(function(){ var $menu = $.ui.contextMenu.activeMenu; if ($menu) $menu.contextMenu('adjust'); }); })(jQuery);