/** * jQuery PopMenu * * Context menu (popup menu) plugin for web applications. * * Copyright © 2014 Fajar Yoseph Chandra. All rights reserved. * * @version 1.0.0 * @author Fajar Chandra * @since 2014.05.29 */ PopMenu=function(menu,options){this.id="PopMenu_"+Math.round(Math.random()*1E7);this.data=PopMenu.defaults;this.$=$('
");this.$menu=this.$.children(".PopMenu-Menu");this.populateMenu(menu);this.$.on("click",function(){var instance=$(this).data("PopMenu.instance");instance.hide()});this.$.on("contextmenu",function(){return false});this.$.on("mousewheel DOMMouseScroll",function(e){e.stopPropagation(); e.preventDefault();return false});this.$menu.on("mousewheel DOMMouseScroll",function(e){if(!$(this).hasClass("overflows"))return false;var marginTop=parseInt($(this).css("margin-top"));if((e.type="DOMMouseScroll"&&e.originalEvent.detail<0)||typeof WheelEvent!="undefined"&&e.originalEvent instanceof WheelEvent&&e.originalEvent.wheelDeltaY>0||typeof MouseEvent!="undefined"&&e.originalEvent instanceof MouseEvent&&e.originalEvent.detail<0||typeof Event!="undefined"&&e.originalEvent instanceof Event&& e.originalEvent.wheelDelta>0){marginTop+=72;if(marginTop>0)marginTop=0}else if((e.type="DOMMouseScroll")||typeof WheelEvent!="undefined"&&e.originalEvent instanceof WheelEvent||typeof MouseEvent!="undefined"&&e.originalEvent instanceof MouseEvent||typeof Event!="undefined"&&e.originalEvent instanceof Event){marginTop-=72;if(marginTop+$(this).data("menu-height")<$(window).height())marginTop=$(window).height()-$(this).data("menu-height")}$(this).stop();$(this).animate({"margin-top":marginTop+"px"}, 100,"linear")});this.$menu.on("mousemove",function(e){if(!$(this).hasClass("overflows"))return false;var $instance=$(this).parent().data("PopMenu.instance");var marginTop=parseInt($(this).css("margin-top"));var duration=0;if(e.pageY-$(window).scrollTop()<$instance.data.scrollerSize){duration=-marginTop;marginTop=0}else if(e.pageY-$(window).scrollTop()>$(window).height()-$instance.data.scrollerSize){duration=marginTop-($(window).height()-$(this).data("menu-height"));marginTop=$(window).height()-$(this).data("menu-height")}else{if($(this).data("is-scrolling-with-scroller")){$(this).stop(); $(this).data("is-scrolling-with-scroller",false)}return}$(this).stop();$(this).data("is-scrolling-with-scroller",true);$(this).animate({"margin-top":marginTop+"px"},duration*3,"linear",function(){$(this).data("is-scrolling-with-scroller",false)})});this.$.data("PopMenu.instance",this);this.options(options)};PopMenu.direction={RIGHT:2,LEFT:0,TOP:0,BOTTOM:1,HORIZONTAL:2,VERTICAL:1,RIGHT_BOTTOM:3,RIGHT_TOP:2,LEFT_BOTTOM:1,LEFT_TOP:0}; PopMenu.defaults={effect:"fade",duration:200,contextMenu:false,tmpFx:undefined,direction:PopMenu.direction.RIGHT_BOTTOM,scrollerSize:24};PopMenu.prototype.options=function(options){if(arguments.length==0)return this.data;this.data=$.extend(true,{},this.data,options);this.effect(this.data.effect);this.duration(this.data.duration);this.contextMenu(this.data.contextMenu)}; PopMenu.prototype.effect=function(effect){if(arguments.length==0)return this.data.effect;switch(effect){case "fade":case "slide":case "none":this.data.effect=effect;return true;default:return false}};PopMenu.prototype.duration=function(duration){if(arguments.length==0)return this.data.duration;this.data.duration=duration}; PopMenu.prototype.contextMenu=function(value){if(arguments.length==0)return this.data.contextMenu;this.data.contextMenu=value;this.$.removeClass("PopMenu");this.$.removeClass("PopMenu-TopMenu");if(this.data.contextMenu){this.$.addClass("PopMenu");this.$menu.addClass("PopMenu-TopMenu");$("body").append(this.$)}}; PopMenu.prototype.show=function(x,y,effect,duration){if(!this.contextMenu())return false;if(effect==null||effect=="default")effect=this.data.effect;if(duration===undefined)duration=this.data.duration;this.data.tmpFx=effect;this.$.css("visibility","hidden");this.$.show();var menuW=this.$menu.outerWidth();var menuH=this.$menu.outerHeight();this.$.hide();this.$.css("visibility","visible");if(x<0)x=0;if(x+menuW>$(window).width()){x-=menuW;if(x+menuW>$(window).width())x=$(window).width()-menuW}if(y<0)y= 0;if(y+menuH>$(window).height()){y-=menuH;if(y+menuH>$(window).height())y=$(window).height()-menuH}this.$menu.css("left",x+"px");this.$menu.css("top",y+"px");this.updateLabels();switch(effect){default:case "none":this.$.show();break;case "fade":this.$.fadeIn(duration);break;case "slide":this.$.slideDown(duration);break}}; PopMenu.prototype.showAsSubmenu=function(direction,effect,duration){var $parent=this.$.parent(".PopMenu-Item");if($parent.length==0)return false;if(effect==null||effect=="default")effect=this.data.effect;if(duration===undefined)duration=this.data.duration;if(direction===undefined)direction=this.data.direction;this.data.tmpFx=effect;this.$menu.removeClass("overflows");this.$menu.css("margin-top",0);if((direction&PopMenu.direction.HORIZONTAL)==PopMenu.direction.RIGHT){this.$menu.css("left","100%"); this.$menu.css("right","auto")}else{this.$menu.css("left","auto");this.$menu.css("right","100%")}if((direction&PopMenu.direction.VERTICAL)==PopMenu.direction.BOTTOM){this.$menu.css("top","0");this.$menu.css("bottom","auto")}else{this.$menu.css("top","auto");this.$menu.css("bottom","0")}this.$.css("visibility","hidden");this.$.show();var menuW=this.$menu.outerWidth();var menuH=this.$menu.outerHeight();var x=this.$menu.offset().left-$(window).scrollLeft();var y=this.$menu.offset().top-$(window).scrollTop(); this.$menu.data("menu-height",menuH);this.$menu.data("menu-width",menuW);this.$.hide();this.$.css("visibility","visible");var parentH=$parent.outerHeight();if((direction&PopMenu.direction.HORIZONTAL)==PopMenu.direction.RIGHT&&x+menuW>$(window).width()){this.$menu.css("left","auto");this.$menu.css("right","100%");this.data.direction=PopMenu.direction.direction&~PopMenu.direction.HORIZONTAL|PopMenu.direction.LEFT}if((direction&PopMenu.direction.HORIZONTAL)==PopMenu.direction.LEFT&&x<0){this.$menu.css("left", "100%");this.$menu.css("right","auto");this.data.direction=PopMenu.direction.direction&~PopMenu.direction.HORIZONTAL|PopMenu.direction.RIGHT}if((direction&PopMenu.direction.VERTICAL)==PopMenu.direction.BOTTOM&&y+menuH>$(window).height()){this.$menu.css("top","auto");this.$menu.css("bottom","0");if(y+parentH-menuH<0){this.$menu.css("top",-y+"px");this.$menu.css("bottom","auto");this.$menu.addClass("overflows")}}if((direction&PopMenu.direction.VERTICAL)==PopMenu.direction.TOP&&y<0){this.$menu.css("top", "0");this.$menu.css("bottom","auto");if(y+parentH>$(window).height()){this.$menu.css("top",-y+"px");this.$menu.css("bottom","auto");this.$menu.addClass("overflows")}}$parent.addClass("selected");switch(effect){default:case "none":this.$.show();break;case "fade":this.$.fadeIn(duration);break;case "slide":this.$.slideDown(duration);break}}; PopMenu.prototype.hide=function(effect,duration){if(effect==null)effect=this.data.tmpFx;if(duration===undefined)duration=this.data.duration;this.hideSubmenus(effect,duration);switch(effect){default:case "none":this.$.hide();break;case "fade":this.$.fadeOut(duration);break;case "slide":this.$.slideUp(duration);break}}; PopMenu.prototype.hideSubmenus=function(effect,duration){this.$.find(".PopMenu-Item.selected").removeClass("selected");switch(effect){default:case "none":this.$.find(".PopMenu-Container").hide();break;case "fade":this.$.find(".PopMenu-Container").fadeOut(duration);break;case "slide":this.$.find(".PopMenu-Container").slideUp(duration);break}};PopMenu.prototype.populateMenu=function(menu){var instance=this;$.each(menu,function(index,item){instance.append(index,item)})}; PopMenu.prototype.find=function(id){var $find=this.$menu.find("a[data-id="+id+"]");if($find.length==0)return null;else return $find.parent().data("PopMenu.instance")};PopMenu.prototype.append=function(id,item){item.id=id;var menuItem=new PopMenuItem(item);this.$menu.append(menuItem.$);return menuItem};PopMenu.prototype.insert=function(id,item,after){item.id=id;var $after=this.find(after).$;var menuItem=new PopMenuItem(item);$after.after(menuItem.$);return menuItem}; PopMenu.prototype.prepend=function(id,item){item.id=id;var menuItem=new PopMenuItem(item);this.$menu.prepend(menuItem.$);return menuItem};PopMenu.prototype.remove=function(id){var item=this.find(id);if(item!=null){item.$.remove();delete item}};PopMenu.prototype.updateLabels=function(force){this.$.find("a.PopMenu-Link").each(function(){var instance=$(this).parent().data("PopMenu.instance");instance.updateLabel(force)})}; PopMenu.prototype.selectedItem=function(){var selected=this.$.find(".PopMenu-Item.selected");if(selected.length>0)return selected.data("PopMenu.instance");else return null}; PopMenuItem=function(options){this.data=PopMenuItem.defaults;this.callbacks={};this.$=$('