pool/web/yaamp/ui/js/jquery.dialogextend.js
2015-07-02 20:58:45 +02:00

589 lines
No EOL
20 KiB
JavaScript

/*!
* jQuery DialogExtend 1.0
*
* Copyright (c) 2010 Shum Ting Hin
*
* Licensed under MIT
* http://www.opensource.org/licenses/mit-license.php
*
* Project Home:
* http://code.google.com/p/jquery-dialogextend/
*
* Depends:
* jQuery 1.4
* jQuery UI Dialog 1.8.0
*
* History:
* 0.9 / 2010-11-04 / hin / creation of plugin
* 0.9.1 / 2010-11-16 / hin / fix bug of zero-config
* 0.9.2 / 2010-12-16 / hin / fix bug of not firing <load.dialogExtend> event
* apply <events> as init option for defining event-callback
* 1.0 / 2010-01-05 / hin / fix bug of button-pane in 'minimized' state
* fix bug of title-bar word-wrap in 'minimized' state
* apply <titlebar=none|transparent> as init option for enhancing title-bar feature
* apply <dblclick=collapse> as init option for enhancing double-click feature
*
*/
(function($){
//default settings
var defaults = {
"maximize" : false,
"minimize" : false,
"dblclick" : false,
"titlebar" : false,
"icons" : {
"maximize" : "ui-icon-extlink",
"minimize" : "ui-icon-minus",
"restore" : "ui-icon-newwin"
},
"events" : {
"load" : null,
"beforeCollapse" : null,
"beforeMaximize" : null,
"beforeMinimize" : null,
"beforeRestore" : null,
"collapse" : null,
"maximize" : null,
"minimize" : null,
"restore" : null
}
};
//plugin settings (will be modified during init)
var settings;
//plubic methods
var methods = {
"init" : function( options ){
var self = this;
//validation
if ( !$(self).dialog ) {
$.error( "jQuery.dialogExtend Error : Only jQuery UI Dialog element is accepted" );
}
//merge defaults & options, without modifying the defaults
options = options || {};
options.icons = options.icons || {};
options.events = options.events || {};
settings = $.extend({}, defaults, options);
settings.icons = $.extend({}, defaults.icons, options.icons);
settings.events = $.extend({}, defaults.events, options.events);
//initiate plugin...
$(self).each(function(){
$(this)
//set default dialog state
.data("dialog-state", "normal")
//do bunch of things...
.dialogExtend("_verifySettings")
.dialogExtend("_initEvents")
.dialogExtend("_initStyles")
.dialogExtend("_initButtons")
.dialogExtend("_initTitleBar")
//trigger custom event when done
.dialogExtend("_trigger", "load");
});
//maintain chainability
return self;
},
"collapse" : function(){
var self = this;
//calculate new dimension
var newHeight = $(this).dialog("widget").find(".ui-dialog-titlebar").height()+15;
//start!
$(self)
//trigger custom event
.dialogExtend("_trigger", "beforeCollapse")
//remember original state
.dialogExtend("_saveSnapshot")
//mark new state
.data("dialog-state", "collapsed")
//modify dialog size (after hiding content)
.dialog("option", {
"height" : newHeight,
"maxHeight" : newHeight
})
//hide content
//hide button-pane
//make title-bar no-wrap
.hide()
.dialog("widget")
.find(".ui-dialog-buttonpane:visible").hide().end()
.find(".ui-dialog-titlebar").css("white-space", "nowrap").end()
.find(".ui-dialog-content")
//trigger custom event
.dialogExtend("_trigger", "collapse");
//maintain chainability
return self;
},
"maximize" : function(){
var self = this;
//caculate new dimension
var newHeight = $(window).height()-11;
var newWidth = $(window).width()-11;
//start!
$(self)
//trigger custom event
.dialogExtend("_trigger", "beforeMaximize")
//remember original state
.dialogExtend("_saveSnapshot")
//mark new state
.data("dialog-state", "maximized")
//modify dialog button
.dialogExtend("_toggleButtons")
//fix dialog from scrolling
.dialog("widget")
.css("position", "fixed")
.find(".ui-dialog-content")
//show content
//show button-pane (when minimized/collapsed)
.show()
.dialog("widget")
.find(".ui-dialog-buttonpane").show().end()
.find(".ui-dialog-content")
//modify dialog with new config
.dialog("option", {
"resizable" : false,
"draggable" : false,
"height" : newHeight,
"width" : newWidth,
"position" : [1, 1]
})
//disable draggable-handle (for <titlebar=none> only)
.dialog("widget")
// .draggable("option", "handle", null)
.find(".ui-dialog-draggable-handle").css("cursor", "text").end()
.find(".ui-dialog-content")
//trigger custom event
.dialogExtend("_trigger", "maximize");
//maintain chainability
return self;
},
"minimize" : function(){
var self = this;
var container = "#minimized-dialog-container";
//caculate new dimension
var newHeight = $(this).dialog("widget").find(".ui-dialog-titlebar").height()+15;
var newWidth = 200;
//create container for (multiple) minimized dialogs (when necessary)
if ( !$(container).length ) {
$("<div />")
.attr("id", container.replace("#", ""))
.css({ "left" : 1, "bottom" : 1, "position" : "fixed" })
.appendTo("body");
}
//start!
$(self)
//trigger custom event
.dialogExtend("_trigger", "beforeMinimize")
//remember original state
.dialogExtend("_saveSnapshot")
//mark new state
.data("dialog-state", "minimized")
//modify dialog button
.dialogExtend("_toggleButtons")
//move dialog from body to container
.dialog("widget")
.css({
"float" : "left", //float is essential for stacking
"margin" : 1,
"position" : "static"
})
.appendTo(container)
.find(".ui-dialog-content")
//modify dialog with new config
.dialog("option", {
"resizable" : false,
"draggable" : false,
"height" : newHeight,
"width" : newWidth
})
//hide content
//hide button-pane
//make title-bar no-wrap
.hide()
.dialog("widget")
.find(".ui-dialog-buttonpane:visible").hide().end()
.find(".ui-dialog-titlebar").css("white-space", "nowrap").end()
.find(".ui-dialog-content")
//disable draggable-handle (for <titlebar=none> only)
.dialog("widget")
.draggable("option", "handle", null)
.find(".ui-dialog-draggable-handle").css("cursor", "text").end()
.find(".ui-dialog-content")
//trigger custom event
.dialogExtend("_trigger", "minimize");
//maintain chainability
return self;
},
"restore" : function(){
var self = this;
var beforeState = $(self).data("dialog-state");
//start!
$(self)
//trigger custom event
.dialogExtend("_trigger", "beforeRestore")
//mark new state
.data("dialog-state", "normal")
//restore dialog button
.dialogExtend("_toggleButtons")
//restore dialog according to previous state
.dialogExtend(
beforeState == "maximized" ? "_restoreFromMaximized" :
beforeState == "minimized" ? "_restoreFromMinimized" :
beforeState == "collapsed" ? "_restoreFromCollapsed" :
$.error( "jQuery.dialogExtend Error : Cannot restore dialog from unknown state '" + beforeState +"'" )
)
//trigger custom event
.dialogExtend("_trigger", "restore");
//maintain chainability
return self;
},
"_initButtons" : function(){
var self = this;
//start operation on titlebar
var titlebar = $(self).dialog("widget").find(".ui-dialog-titlebar");
$(titlebar)
.append('<a class="ui-dialog-titlebar-maximize ui-corner-all" href="#"><span class="ui-icon '+settings.icons.maximize+'">maximize</span></a>')
.append('<a class="ui-dialog-titlebar-minimize ui-corner-all" href="#"><span class="ui-icon '+settings.icons.minimize+'">minimize</span></a>')
.append('<a class="ui-dialog-titlebar-restore ui-corner-all" href="#"><span class="ui-icon '+settings.icons.restore+'">restore</span></a>')
//add effect to buttons
.find(".ui-dialog-titlebar-maximize,.ui-dialog-titlebar-minimize,.ui-dialog-titlebar-restore")
.attr("role", "button")
.mouseover(function(){ $(this).addClass("ui-state-hover"); })
.mouseout(function(){ $(this).removeClass("ui-state-hover"); })
.focus(function(){ $(this).addClass("ui-state-focus"); })
.blur(function(){ $(this).removeClass("ui-state-focus"); })
.end()
//default show buttons
//set button positions
//on-click-button
.find(".ui-dialog-titlebar-maximize")
.toggle(settings.maximize)
.css({ "right" : settings.maximize ? "1.4em" : "-9999em" })
.click(function(e){
e.preventDefault();
$(self).dialogExtend("maximize");
})
.end()
.find(".ui-dialog-titlebar-minimize")
.toggle(settings.minimize)
.css({ "right" : settings.maximize ? "2.5em" : settings.minimize ? "1.4em" : "-9999em" })
.click(function(e){
e.preventDefault();
$(self).dialogExtend("minimize");
})
.end()
.find(".ui-dialog-titlebar-restore")
.hide()
.css({ "right" : "-9999em" })
.click(function(e){
e.preventDefault();
$(self).dialogExtend("restore");
})
.end()
//on-dblclick-titlebar : maximize/minimize/collapse/restore
.dblclick(function(evt){
if ( settings.dblclick && settings.dblclick.length ) {
$(self).dialogExtend( $(self).data("dialog-state") != "normal" ? "restore" : settings.dblclick );
}
})
//avoid text-highlight when double-click
.each(function(){
$(this)
//.attr("unselectable", "on")
//.css({ "-moz-user-select" : "none", "-khtml-user-select" : "none" })
.select(function(){ return false; });
});
//maintain chainability
return self;
},
"_initEvents" : function(){
var self = this;
//bind event callbacks which specified at init
$.each(settings.events, function(type){
if ( $.isFunction( settings.events[type] ) ) {
$(self).bind(type+".dialogExtend", settings.events[type]);
}
});
//maintain chainability
return self;
},
"_initStyles" : function(){
var self = this;
//append styles for this plugin to body
var style = '';
style += '<style type="text/css">';
style += '.ui-dialog .ui-dialog-titlebar-maximize,';
style += '.ui-dialog .ui-dialog-titlebar-minimize,';
style += '.ui-dialog .ui-dialog-titlebar-restore { position: absolute; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }';
style += '.ui-dialog .ui-dialog-titlebar-maximize span,';
style += '.ui-dialog .ui-dialog-titlebar-minimize span,';
style += '.ui-dialog .ui-dialog-titlebar-restore span { display: block; margin: 1px; }';
style += '.ui-dialog .ui-dialog-titlebar-maximize:hover,';
style += '.ui-dialog .ui-dialog-titlebar-maximize:focus,';
style += '.ui-dialog .ui-dialog-titlebar-minimize:hover,';
style += '.ui-dialog .ui-dialog-titlebar-minimize:focus,';
style += '.ui-dialog .ui-dialog-titlebar-restore:hover,';
style += '.ui-dialog .ui-dialog-titlebar-restore:focus { padding: 0; }';
style += '.ui-dialog .ui-dialog-titlebar ::selection { background-color: transparent; }';
style += '</style>';
$(style).appendTo("body");
//maintain chainability
return self;
},
"_initTitleBar" : function(){
var self = this;
//modify title bar
switch ( settings.titlebar ) {
case false:
//do nothing
break;
case "none":
//create new draggable-handle as substitute of title bar
if ( $(self).dialog("option", "draggable") ) {
var handle = $("<div />").addClass("ui-dialog-draggable-handle").css("cursor", "move").height(5);
$(self).dialog("widget").prepend(handle).draggable("option", "handle", handle);
}
//remove title bar and keep it draggable
$(self)
.dialog("widget")
.find(".ui-dialog-titlebar")
//clear title text
.find(".ui-dialog-title").html("&nbsp;").end()
//keep buttons at upper-right-hand corner
.css({
"background-color" : "transparent",
"background-image" : "none",
"border" : 0,
"position" : "absolute",
"right" : 0,
"top" : 0,
"z-index" : 9999
})
.end();
break;
case "transparent":
//remove title style
$(self)
.dialog("widget")
.find(".ui-dialog-titlebar")
.css({
"background-color" : "transparent",
"background-image" : "none",
"border" : 0
});
break;
default:
$.error( "jQuery.dialogExtend Error : Invalid <titlebar> value '" + settings.titlebar + "'" );
}
//maintain chainability
return self;
},
"_loadSnapshot" : function(){
var self = this;
return {
"config" : {
"resizable" : $(self).data("original-config-resizable"),
"draggable" : $(self).data("original-config-draggable")
},
"size" : {
"height" : $(self).data("original-size-height"),
"width" : $(self).data("original-size-width"),
"maxHeight" : $(self).data("original-size-maxHeight")
},
"position" : {
"mode" : $(self).data("original-position-mode"),
"left" : $(self).data("original-position-left"),
"top" : $(self).data("original-position-top")
},
"titlebar" : {
"wrap" : $(self).data("original-titlebar-wrap")
}
};
},
"_restoreFromCollapsed" : function(){
var self = this;
var original = $(this).dialogExtend("_loadSnapshot");
//restore dialog
$(self)
//show content
//show button-pane
//fix title-bar wrap
.show()
.dialog("widget")
.find(".ui-dialog-buttonpane:hidden").show().end()
.find(".ui-dialog-titlebar").css("white-space", original.titlebar.wrap).end()
.find(".ui-dialog-content")
//restore config & size
.dialog("option", {
"height" : original.size.height,
"maxHeight" : original.size.maxHeight
});
//maintain chainability
return self;
},
"_restoreFromMaximized" : function(){
var self = this;
var original = $(this).dialogExtend("_loadSnapshot");
//restore dialog
$(self)
//free dialog from scrolling
//fix title-bar wrap (if dialog was minimized/collapsed)
.dialog("widget")
.css("position", original.position.mode)
.find(".ui-dialog-titlebar").css("white-space", original.titlebar.wrap).end()
.find(".ui-dialog-content")
//restore config & size & position
.dialog("option", {
"resizable" : original.config.resizable,
"draggable" : original.config.draggable,
"height" : original.size.height,
"width" : original.size.width,
"maxHeight" : original.size.maxHeight,
"position" : [ original.position.left, original.position.top ]
})
//restore draggable-handle (for <titlebar=none> only)
.dialog("widget")
.draggable("option", "handle", $(this).find(".ui-dialog-draggable-handle"))
.find(".ui-dialog-draggable-handle")
.css("cursor", "move");
//maintain chainability
return self;
},
"_restoreFromMinimized" : function(){
var self = this;
var original = $(this).dialogExtend("_loadSnapshot");
var container = "#minimized-dialog-container";
//restore dialog
$(self)
//move dialog back from container to body
.dialog("widget")
.appendTo("body")
.css({
"float" : "none",
"margin" : 0,
"position" : original.position.mode
})
.find(".ui-dialog-content")
//show content
//show button-pane
//fix title-bar wrap
.show()
.dialog("widget")
.find(".ui-dialog-buttonpane:hidden").show().end()
.find(".ui-dialog-titlebar").css("white-space", original.titlebar.wrap).end()
.find(".ui-dialog-content")
//restore config & size & position
.dialog("option", {
"resizable" : original.config.resizable,
"draggable" : original.config.draggable,
"height" : original.size.height,
"width" : original.size.width,
"maxHeight" : original.size.maxHeight,
"position" : [ original.position.left, original.position.top ]
})
//restore draggable-handle (for <titlebar=none> only)
.dialog("widget")
.draggable("option", "handle", $(this).find(".ui-dialog-draggable-handle"))
.find(".ui-dialog-draggable-handle")
.css("cursor", "move");
//maintain chainability
return self;
},
"_saveSnapshot" : function(){
var self = this;
//remember all configs under normal state
if ( $(self).data("dialog-state") == "normal" ) {
$(self)
.data("original-config-resizable", $(self).dialog("option", "resizable"))
.data("original-config-draggable", $(self).dialog("option", "draggable"))
.data("original-size-height", $(self).dialog("widget").height())
.data("original-size-width", $(self).dialog("option", "width"))
.data("original-size-maxHeight", $(self).dialog("option", "maxHeight"))
.data("original-position-mode", $(self).dialog("widget").css("position"))
.data("original-position-left", $(self).dialog("widget").offset().left)
.data("original-position-top", $(self).dialog("widget").offset().top)
.data("original-titlebar-wrap", $(self).dialog("widget").find(".ui-dialog-titlebar").css("white-space"));
}
//maintain chainability
return self;
},
"_toggleButtons" : function(){
var self = this;
//show or hide buttons & decide position
$(self).dialog("widget")
.find(".ui-dialog-titlebar-maximize")
.toggle( $(self).data("dialog-state") != "maximized" && settings.maximize )
.end()
.find(".ui-dialog-titlebar-minimize")
.toggle( $(self).data("dialog-state") != "minimized" && settings.minimize )
.end()
.find(".ui-dialog-titlebar-restore")
.toggle( $(self).data("dialog-state") != "normal" && ( settings.maximize || settings.minimize ) )
.css({ "right" : $(self).data("dialog-state") == "maximized" ? "1.4em" : $(self).data("dialog-state") == "minimized" ? !settings.maximize ? "1.4em" : "2.5em" : "-9999em" })
.end();
//maintain chainability
return self;
},
"_trigger" : function( type ){
var self = this;
//trigger event with namespace when user bind to it
$(self).triggerHandler(type+".dialogExtend", this);
//maintain chainability
return self;
},
"_verifySettings" : function(){
var self = this;
//check <dblclick> option
if ( !settings.dblclick ) {
} else if ( settings.dblclick == "maximize" ) {
} else if ( settings.dblclick == "minimize" ) {
} else if ( settings.dblclick == "collapse" ) {
} else {
$.error( "jQuery.dialogExtend Error : Invalid <dblclick> value '" + settings.dblclick + "'" );
settings.dblclick = false;
}
//check <titlebar> option
if ( !settings.titlebar ) {
} else if ( settings.titlebar == "none" ) {
} else if ( settings.titlebar == "transparent" ) {
} else {
$.error( "jQuery.dialogExtend Error : Invalid <titlebar> value '" + settings.titlebar + "'" );
settings.titlebar = false;
}
//maintain chainability
return self;
}
};
//core method
$.fn.dialogExtend = function( method ){
//method calling logic
if ( methods[ method ] ) {
return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ) );
} else if ( typeof method === "object" || ! method ) {
return methods.init.apply( this, arguments );
} else {
$.error( "jQuery.dialogExtend Error : Method <" + method + "> does not exist" );
}
};
}(jQuery));