new jjmenu for dynamic context menus. playlists in library.
need to work on javascript callback
This commit is contained in:
parent
4bdcba83e2
commit
d2b1bf0622
17 changed files with 545 additions and 318 deletions
366
public/js/contextmenu/jjmenu.js
Normal file
366
public/js/contextmenu/jjmenu.js
Normal file
|
@ -0,0 +1,366 @@
|
|||
/* jjmenu - context menu jquery plugin
|
||||
* http://jursza.net/dev/jjmenu/
|
||||
*
|
||||
* @author Jacek Jursza (okhan.pl@gmail.com)
|
||||
* @version 1.1.2
|
||||
* @date 2010-08-28
|
||||
* @category jQuery plugin
|
||||
* @copyright (c) 2009 Jacek Jursza (http://jursza.net/)
|
||||
* @licence MIT [http://www.opensource.org/licenses/mit-license.php]
|
||||
*/
|
||||
|
||||
(function($){
|
||||
|
||||
$.fn.jjmenu = function (clickEvent, param, myReplaces, effect) {
|
||||
|
||||
var global = this;
|
||||
var acceptEvent = false;
|
||||
|
||||
|
||||
if ( clickEvent == "rightClick" || clickEvent == "both" )
|
||||
{
|
||||
global.mousedown(function(event) {
|
||||
if (event.button == 2 && (clickEvent == "rightClick" || clickEvent == "both")) { // right click
|
||||
global.pageX = event.pageX;
|
||||
global.pageY = event.pageY;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var mmain = new menu("main", param, myReplaces, this, effect);
|
||||
$(this)[0].oncontextmenu = function() {
|
||||
return false;
|
||||
}
|
||||
$(this).unbind('mouseup');
|
||||
$(this).blur();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
document.body.oncontextmenu = function() {
|
||||
if ($("div[id^=jjmenu_main]").length) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( clickEvent == "click" || clickEvent == "both" )
|
||||
{
|
||||
global.click(
|
||||
function(event) {
|
||||
if (this == event.target) {
|
||||
global.pageX = event.pageX;
|
||||
global.pageY = event.pageY;
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
var mmain = new menu("main", param, myReplaces, this, effect);
|
||||
$(this).blur();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).click(function(event) { if (event.button!=2) $("div[id^=jjmenu]").remove(); });
|
||||
|
||||
/* Menu obeject */
|
||||
function menu(id,param,myReplaces,el,effect) {
|
||||
|
||||
var effect = getEffect(id, effect);
|
||||
|
||||
if (id == "main") window.triggerElement = el;
|
||||
$("div[id^=jjmenu_"+id+"]").remove();
|
||||
|
||||
var m = document.createElement('div');
|
||||
var ms = document.createElement('span');
|
||||
$(m).append(ms);
|
||||
|
||||
m.className = "jjmenu"; m.id = "jjmenu_"+id;
|
||||
$(m).css({display:'none'});
|
||||
$(document.body).append(m);
|
||||
|
||||
positionMenu();
|
||||
|
||||
var dynamicItems = false;
|
||||
|
||||
for (var i in param) {
|
||||
|
||||
if (param[i].get) {
|
||||
|
||||
dynamicItems = true;
|
||||
$.getJSON(uReplace(param[i].get), function(data) {
|
||||
for (var ii in data) {
|
||||
putItem(data[ii]);
|
||||
}
|
||||
checkPosition();
|
||||
})
|
||||
$(this).ajaxError( function() {
|
||||
checkPosition();
|
||||
});
|
||||
}
|
||||
else if (param[i].getByFunction) {
|
||||
|
||||
if (typeof(param[i].getByFunction) == "function") {
|
||||
var uF = param[i].getByFunction;
|
||||
}
|
||||
else {
|
||||
var uF = eval(param[i].getByFunction);
|
||||
}
|
||||
var uItems = uF(myReplaces);
|
||||
for (var ii in uItems) {
|
||||
putItem(uItems[ii]);
|
||||
}
|
||||
checkPosition();
|
||||
}
|
||||
else {
|
||||
putItem(param[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!dynamicItems) checkPosition();
|
||||
showMenu();
|
||||
|
||||
/* first position menu */
|
||||
function positionMenu() {
|
||||
|
||||
var pos = $(el).offset();
|
||||
|
||||
var t = pos.top;
|
||||
|
||||
if (effect.xposition == "left") {
|
||||
var l = pos.left;
|
||||
}
|
||||
else {
|
||||
var l = pos.left+$(el).width()+10;
|
||||
}
|
||||
|
||||
if (effect.xposition == "mouse") {
|
||||
l = global.pageX;
|
||||
}
|
||||
if (effect.yposition == "mouse") {
|
||||
t = global.pageY;
|
||||
}
|
||||
|
||||
$(m).css({position:"absolute",top:t+"px",left:l+"px"});
|
||||
}
|
||||
|
||||
/* correct menu position */
|
||||
function checkPosition() {
|
||||
|
||||
var isHidden = $(m).css("display") == "none" ? true : false;
|
||||
var noAuto = false;
|
||||
|
||||
if (effect.orientation == "top" || effect.orientation == "bottom") {
|
||||
noAuto = true;
|
||||
}
|
||||
|
||||
if (isHidden) $(m).show();
|
||||
var positionTop = $(m).offset().top;
|
||||
var positionLeft = $(m).offset().left;
|
||||
if (isHidden) $(m).hide();
|
||||
|
||||
var xPos = positionTop - $(window).scrollTop();
|
||||
|
||||
$(m).css({left:"0px"});
|
||||
var menuHeight = $(m).outerHeight();
|
||||
var menuWidth = $(m).outerWidth();
|
||||
$(m).css({left:positionLeft+"px"});
|
||||
|
||||
var nleft = positionLeft;
|
||||
if ( positionLeft + menuWidth > $(window).width() ) {
|
||||
nleft = $(window).width() - menuWidth;
|
||||
}
|
||||
|
||||
var spaceBottom = true;
|
||||
if (effect.yposition == "auto" && effect.xposition == "left") {
|
||||
|
||||
if ( xPos + menuHeight + $(el).outerHeight() > $(window).height()) {
|
||||
spaceBottom = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if ( xPos + menuHeight > $(window).height()) {
|
||||
spaceBottom = false;
|
||||
}
|
||||
}
|
||||
|
||||
var spaceTop = true;
|
||||
if (positionTop - menuHeight < 0) {
|
||||
spaceTop = false;
|
||||
}
|
||||
|
||||
if (effect.yposition == "bottom") {
|
||||
positionTop = positionTop + $(el).outerHeight();
|
||||
}
|
||||
|
||||
if ( (effect.orientation == "auto" && spaceBottom == false && spaceTop == true) || effect.orientation == "top") {
|
||||
// top orientation
|
||||
var ntop = parseInt(positionTop,10) - parseInt(menuHeight,10);
|
||||
$(m).addClass("topOriented");
|
||||
|
||||
} else {
|
||||
// bottom orientation
|
||||
$(m).addClass("bottomOriented");
|
||||
if (effect.yposition == "auto" && effect.xposition == "left") {
|
||||
positionTop = positionTop + $(el).outerHeight();
|
||||
}
|
||||
var ntop = parseInt(positionTop,10);
|
||||
}
|
||||
|
||||
$(m).css({"top":ntop+"px", "left":nleft+"px"});
|
||||
}
|
||||
|
||||
/* show menu depends to effect.show */
|
||||
function showMenu() {
|
||||
|
||||
if (!effect || effect.show == "default") {
|
||||
$(m).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
var speed = parseInt(effect.speed);
|
||||
speed = isNaN(speed) ? 500 : speed;
|
||||
|
||||
switch (effect.show)
|
||||
{
|
||||
case "fadeIn":
|
||||
$(m).fadeIn(speed);
|
||||
break;
|
||||
|
||||
case "slideDown":
|
||||
$(m).slideDown(speed);
|
||||
break;
|
||||
|
||||
default:
|
||||
$(m).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* put item to menu */
|
||||
function putItem(n) {
|
||||
|
||||
var item = document.createElement('div');
|
||||
$(item).hover(function(){
|
||||
$(this).addClass("jj_menu_item_hover")
|
||||
},
|
||||
function(){
|
||||
$(this).removeClass("jj_menu_item_hover")
|
||||
});
|
||||
|
||||
$(item).click( function(event) {
|
||||
event.stopPropagation();
|
||||
doAction(n.action);
|
||||
});
|
||||
|
||||
var span = document.createElement('span');
|
||||
$(item).append(span);
|
||||
|
||||
|
||||
switch (n.type)
|
||||
{
|
||||
case "sub":
|
||||
item.className = "jj_menu_item jj_menu_item_more";
|
||||
$(item).click(function() {
|
||||
if ($("#jjmenu_"+id+"_sub").length > 0) {
|
||||
$("div[id^=jjmenu_"+id+"_sub]").remove();
|
||||
}
|
||||
else {
|
||||
var sub = new menu(id+"_sub", n.src, myReplaces, this, effect);
|
||||
}
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
$(item).hover(function() { $("div[id^=jjmenu_"+id+"_sub]").remove(); });
|
||||
item.className = "jj_menu_item";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (n.customClass && n.customClass.length>0) {
|
||||
jQuery(span).addClass(n.customClass);
|
||||
}
|
||||
|
||||
$(span).html(uReplace(n.title));
|
||||
$(ms).append(item);
|
||||
}
|
||||
|
||||
/* do action on menu item */
|
||||
function doAction(act) {
|
||||
|
||||
if (act) {
|
||||
|
||||
switch (act.type) {
|
||||
|
||||
case "gourl":
|
||||
if (act.target) {
|
||||
var newWindow = window.open(uReplace(act.url), act.target);
|
||||
newWindow.focus();
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
document.location.href=uReplace(act.url);
|
||||
}
|
||||
break;
|
||||
|
||||
case "ajax":
|
||||
$.getJSON(uReplace(act.url), function(data) {
|
||||
|
||||
|
||||
var cb = eval(act.callback);
|
||||
if (typeof(cb) == "function") {
|
||||
cb(data);
|
||||
}
|
||||
|
||||
});
|
||||
break;
|
||||
|
||||
case "fn":
|
||||
var callfn = 'var cb = '+act.callback;
|
||||
jQuery.globalEval(callfn);
|
||||
if (typeof(cb) == "function") {
|
||||
cb(myReplaces);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* replace string with user parameters */
|
||||
function uReplace(str) {
|
||||
if (myReplaces) {
|
||||
for (var u in myReplaces) {
|
||||
str = str.replace("#"+u+"#", eval("myReplaces."+u));
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/* get effect opbject */
|
||||
function getEffect(id, effect) {
|
||||
|
||||
var defEffect = {
|
||||
show:"default",
|
||||
xposition:"right",
|
||||
yposition:"auto",
|
||||
orientation:"auto"
|
||||
};
|
||||
|
||||
if (!effect) { return defEffect; }
|
||||
|
||||
if (!effect.show) effect.show = "default";
|
||||
|
||||
var show = effect.show;
|
||||
|
||||
if (!effect.xposition) effect.xposition = "right";
|
||||
if (!effect.yposition) effect.yposition = "auto";
|
||||
if (!effect.orientation) effect.orientation = "auto";
|
||||
|
||||
if (id != "main") {
|
||||
var subeffect = defEffect;
|
||||
subeffect.show = show;
|
||||
}
|
||||
|
||||
return ( id == "main" ) ? effect : subeffect;
|
||||
}
|
||||
} // !menu
|
||||
};
|
||||
|
||||
})(jQuery);
|
|
@ -1,211 +0,0 @@
|
|||
// jQuery Context Menu Plugin
|
||||
//
|
||||
// Version 1.01
|
||||
//
|
||||
// Cory S.N. LaViska
|
||||
// A Beautiful Site (http://abeautifulsite.net/)
|
||||
//
|
||||
// More info: http://abeautifulsite.net/2008/09/jquery-context-menu-plugin/
|
||||
//
|
||||
// Terms of Use
|
||||
//
|
||||
// This plugin is dual-licensed under the GNU General Public License
|
||||
// and the MIT License and is copyright A Beautiful Site, LLC.
|
||||
//
|
||||
if(jQuery)( function() {
|
||||
$.extend($.fn, {
|
||||
|
||||
contextMenu: function(o, callback) {
|
||||
// Defaults
|
||||
if( o.menu == undefined ) return false;
|
||||
if( o.inSpeed == undefined ) o.inSpeed = 150;
|
||||
if( o.outSpeed == undefined ) o.outSpeed = 75;
|
||||
// 0 needs to be -1 for expected results (no fade)
|
||||
if( o.inSpeed == 0 ) o.inSpeed = -1;
|
||||
if( o.outSpeed == 0 ) o.outSpeed = -1;
|
||||
// Loop each context menu
|
||||
$(this).each( function() {
|
||||
var el = $(this);
|
||||
var offset = $(el).offset();
|
||||
// Add contextMenu class
|
||||
$('#' + o.menu).addClass('contextMenu');
|
||||
// Simulate a true right click
|
||||
$(this).mousedown( function(e) {
|
||||
var evt = e;
|
||||
evt.stopPropagation();
|
||||
$(this).mouseup( function(e) {
|
||||
e.stopPropagation();
|
||||
var srcElement = $(this);
|
||||
$(this).unbind('mouseup');
|
||||
if( evt.button == 2 ) {
|
||||
// Hide context menus that may be showing
|
||||
$(".contextMenu").hide();
|
||||
// Get this context menu
|
||||
var menu = $('#' + o.menu);
|
||||
|
||||
if( $(el).hasClass('disabled') ) return false;
|
||||
|
||||
// Detect mouse position
|
||||
var d = {}, x, y;
|
||||
if( self.innerHeight ) {
|
||||
d.pageYOffset = self.pageYOffset;
|
||||
d.pageXOffset = self.pageXOffset;
|
||||
d.innerHeight = self.innerHeight;
|
||||
d.innerWidth = self.innerWidth;
|
||||
} else if( document.documentElement &&
|
||||
document.documentElement.clientHeight ) {
|
||||
d.pageYOffset = document.documentElement.scrollTop;
|
||||
d.pageXOffset = document.documentElement.scrollLeft;
|
||||
d.innerHeight = document.documentElement.clientHeight;
|
||||
d.innerWidth = document.documentElement.clientWidth;
|
||||
} else if( document.body ) {
|
||||
d.pageYOffset = document.body.scrollTop;
|
||||
d.pageXOffset = document.body.scrollLeft;
|
||||
d.innerHeight = document.body.clientHeight;
|
||||
d.innerWidth = document.body.clientWidth;
|
||||
}
|
||||
(e.pageX) ? x = e.pageX : x = e.clientX + d.scrollLeft;
|
||||
(e.pageY) ? y = e.pageY : y = e.clientY + d.scrollTop;
|
||||
|
||||
// Show the menu
|
||||
$(document).unbind('click');
|
||||
$(menu).css({ top: y, left: x }).fadeIn(o.inSpeed);
|
||||
// Hover events
|
||||
$(menu).find('A').mouseover( function() {
|
||||
$(menu).find('LI.hover').removeClass('hover');
|
||||
$(this).parent().addClass('hover');
|
||||
}).mouseout( function() {
|
||||
$(menu).find('LI.hover').removeClass('hover');
|
||||
});
|
||||
|
||||
// Keyboard
|
||||
$(document).keypress( function(e) {
|
||||
switch( e.keyCode ) {
|
||||
case 38: // up
|
||||
if( $(menu).find('LI.hover').size() == 0 ) {
|
||||
$(menu).find('LI:last').addClass('hover');
|
||||
} else {
|
||||
$(menu).find('LI.hover').removeClass('hover').prevAll('LI:not(.disabled)').eq(0).addClass('hover');
|
||||
if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:last').addClass('hover');
|
||||
}
|
||||
break;
|
||||
case 40: // down
|
||||
if( $(menu).find('LI.hover').size() == 0 ) {
|
||||
$(menu).find('LI:first').addClass('hover');
|
||||
} else {
|
||||
$(menu).find('LI.hover').removeClass('hover').nextAll('LI:not(.disabled)').eq(0).addClass('hover');
|
||||
if( $(menu).find('LI.hover').size() == 0 ) $(menu).find('LI:first').addClass('hover');
|
||||
}
|
||||
break;
|
||||
case 13: // enter
|
||||
$(menu).find('LI.hover A').trigger('click');
|
||||
break;
|
||||
case 27: // esc
|
||||
$(document).trigger('click');
|
||||
break
|
||||
}
|
||||
});
|
||||
|
||||
// When items are selected
|
||||
$('#' + o.menu).find('A').unbind('click');
|
||||
$('#' + o.menu).find('LI:not(.disabled) A').click( function() {
|
||||
$(document).unbind('click').unbind('keypress');
|
||||
$(".contextMenu").hide();
|
||||
// Callback
|
||||
if( callback ) callback( $(this).attr('href').substr(1), $(srcElement), {x: x - offset.left, y: y - offset.top, docX: x, docY: y} );
|
||||
return false;
|
||||
});
|
||||
|
||||
// Hide bindings
|
||||
setTimeout( function() { // Delay for Mozilla
|
||||
$(document).click( function() {
|
||||
$(document).unbind('click').unbind('keypress');
|
||||
$(menu).fadeOut(o.outSpeed);
|
||||
return false;
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Disable text selection
|
||||
if( $.browser.mozilla ) {
|
||||
$('#' + o.menu).each( function() { $(this).css({ 'MozUserSelect' : 'none' }); });
|
||||
} else if( $.browser.msie ) {
|
||||
$('#' + o.menu).each( function() { $(this).bind('selectstart.disableTextSelect', function() { return false; }); });
|
||||
} else {
|
||||
$('#' + o.menu).each(function() { $(this).bind('mousedown.disableTextSelect', function() { return false; }); });
|
||||
}
|
||||
// Disable browser context menu (requires both selectors to work in IE/Safari + FF/Chrome)
|
||||
$(el).add($('UL.contextMenu')).bind('contextmenu', function() { return false; });
|
||||
|
||||
});
|
||||
return $(this);
|
||||
},
|
||||
|
||||
// Disable context menu items on the fly
|
||||
disableContextMenuItems: function(o) {
|
||||
if( o == undefined ) {
|
||||
// Disable all
|
||||
$(this).find('LI').addClass('disabled');
|
||||
return( $(this) );
|
||||
}
|
||||
$(this).each( function() {
|
||||
if( o != undefined ) {
|
||||
var d = o.split(',');
|
||||
for( var i = 0; i < d.length; i++ ) {
|
||||
$(this).find('A[href="' + d[i] + '"]').parent().addClass('disabled');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
return( $(this) );
|
||||
},
|
||||
|
||||
// Enable context menu items on the fly
|
||||
enableContextMenuItems: function(o) {
|
||||
if( o == undefined ) {
|
||||
// Enable all
|
||||
$(this).find('LI.disabled').removeClass('disabled');
|
||||
return( $(this) );
|
||||
}
|
||||
$(this).each( function() {
|
||||
if( o != undefined ) {
|
||||
var d = o.split(',');
|
||||
for( var i = 0; i < d.length; i++ ) {
|
||||
$(this).find('A[href="' + d[i] + '"]').parent().removeClass('disabled');
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
return( $(this) );
|
||||
},
|
||||
|
||||
// Disable context menu(s)
|
||||
disableContextMenu: function() {
|
||||
$(this).each( function() {
|
||||
$(this).addClass('disabled');
|
||||
});
|
||||
return( $(this) );
|
||||
},
|
||||
|
||||
// Enable context menu(s)
|
||||
enableContextMenu: function() {
|
||||
$(this).each( function() {
|
||||
$(this).removeClass('disabled');
|
||||
});
|
||||
return( $(this) );
|
||||
},
|
||||
|
||||
// Destroy context menu(s)
|
||||
destroyContextMenu: function() {
|
||||
// Destroy specified context menus
|
||||
$(this).each( function() {
|
||||
// Disable action
|
||||
$(this).unbind('mousedown').unbind('mouseup');
|
||||
});
|
||||
return( $(this) );
|
||||
}
|
||||
|
||||
});
|
||||
})(jQuery);
|
Loading…
Add table
Add a link
Reference in a new issue