diff --git a/js/functions.js b/js/functions.js index b0fc717652..f67b6a9c97 100644 --- a/js/functions.js +++ b/js/functions.js @@ -1291,62 +1291,136 @@ $(document).ready(function(){ /** * Show a message on the top of the page for an Ajax request * - * @param var message string containing the message to be shown. + * Sample usage: + * + * 1) var $msg = PMA_ajaxShowMessage(); + * This will show a message that reads "Loading...". Such a message will not + * disappear automatically and cannot be dismissed by the user. To remove this + * message either the PMA_ajaxRemoveMessage($msg) function must be called or + * another message must be show with PMA_ajaxShowMessage() function. + * + * 2) var $msg = PMA_ajaxShowMessage(PMA_messages['strProcessingRequest']); + * This is a special case. The behaviour is same as above, + * just with a different message + * + * 3) var $msg = PMA_ajaxShowMessage('The operation was successful'); + * This will show a message that will disappear automatically and it can also + * be dismissed by the user. + * + * 4) var $msg = PMA_ajaxShowMessage('Some error', false); + * This will show a message that will not disappear automatically, but it + * can be dismissed by the user after he has finished reading it. + * + * @param string message string containing the message to be shown. * optional, defaults to 'Loading...' - * @param var timeout number of milliseconds for the message to be visible - * optional, defaults to 5000 + * @param mixed timeout number of milliseconds for the message to be visible + * optional, defaults to 5000. If set to 'false', the + * notification will never disappear * @return jQuery object jQuery Element that holds the message div + * this object can be passed to PMA_ajaxRemoveMessage() + * to remove the notification */ function PMA_ajaxShowMessage(message, timeout) { - - //Handle the case when a empty data.message is passed. We don't want the empty message + /** + * @var self_closing Whether the notification will automatically disappear + */ + var self_closing = true; + /** + * @var dismissable Whether the user will be able to remove + * the notification by clicking on it + */ + var dismissable = true; + // Handle the case when a empty data.message is passed. + // We don't want the empty message if (message == '') { return true; } else if (! message) { // If the message is undefined, show the default message = PMA_messages['strLoading']; + dismissable = false; + self_closing = false; + } else if (message == PMA_messages['strProcessingRequest']) { + // This is another case where the message should not disappear + dismissable = false; + self_closing = false; } - - /** - * @var timeout Number of milliseconds for which the message will be visible - * @default 5000 ms - */ - if (! timeout) { + // Figure out whether (or after how long) to remove the notification + if (timeout == undefined) { timeout = 5000; + } else if (timeout === false) { + self_closing = false; } - // Create a parent element for the AJAX messages, if necessary if ($('#loading_parent').length == 0) { $('
') .insertBefore("#serverinfo"); } - // Update message count to create distinct message elements every time ajax_message_count++; - // Remove all old messages, if any $(".ajax_notification[id^=ajax_message_num]").remove(); - /** * @var $retval a jQuery object containing the reference * to the created AJAX message */ - var $retval = $('') - .hide() - .appendTo("#loading_parent") - .html(message) - .fadeIn('medium') + var $retval = $( + '' + ) + .hide() + .appendTo("#loading_parent") + .html(message) + .fadeIn('medium'); + // If the notification is self-closing we should create a callback to remove it + if (self_closing) { + $retval .delay(timeout) .fadeOut('medium', function() { + if ($(this).is('.dismissable')) { + // Here we should destroy the qtip instance, but + // due to a bug in qtip's implementation we can + // only hide it without throwing JS errors. + $(this).qtip('hide'); + } + // Remove the notification $(this).remove(); }); + } + // If the notification is dismissable we need to add the relevant class to it + // and add a tooltip so that the users know that it can be removed + if (dismissable) { + $retval.addClass('dismissable').css('cursor', 'pointer'); + /** + * @var qOpts Options for "Dismiss notification" tooltip + */ + var qOpts = { + show: { + effect: { length: 0 }, + delay: 0 + }, + hide: { + effect: { length: 0 }, + delay: 0 + } + }; + /** + * Add a tooltip to the notification to let the user know that (s)he + * can dismiss the ajax notification by clicking on it. + */ + PMA_createqTip($retval, PMA_messages['strDismiss'], qOpts); + } return $retval; } /** * Removes the message shown for an Ajax operation when it's completed + * + * @param jQuery object jQuery Element that holds the notification + * + * @return nothing */ function PMA_ajaxRemoveMessage($this_msgbox) { @@ -1354,9 +1428,37 @@ function PMA_ajaxRemoveMessage($this_msgbox) $this_msgbox .stop(true, true) .fadeOut('medium'); + if ($this_msgbox.is('.dismissable')) { + // Here we should destroy the qtip instance, but + // due to a bug in qtip's implementation we can + // only hide it without throwing JS errors. + $this_msgbox.qtip('hide'); + } } } +$(document).ready(function() { + /** + * Allows the user to dismiss a notification + * created with PMA_ajaxShowMessage() + */ + $('.ajax_notification.dismissable').live('click', function () { + PMA_ajaxRemoveMessage($(this)); + }); + /** + * The below two functions hide the "Dismiss notification" tooltip when a user + * is hovering a link or button that is inside an ajax message + */ + $('.ajax_notification a, .ajax_notification button, .ajax_notification input') + .live('mouseover', function () { + $(this).parents('.ajax_notification').qtip('hide'); + }); + $('.ajax_notification a, .ajax_notification button, .ajax_notification input') + .live('mouseout', function () { + $(this).parents('.ajax_notification').qtip('show'); + }); +}); + /** * Hides/shows the "Open in ENUM/SET editor" message, depending on the data type of the column currently selected */ @@ -2895,7 +2997,7 @@ var toggleButton = function ($obj) { } else { $(this).addClass('isActive'); } - var $msg = PMA_ajaxShowMessage(PMA_messages['strLoading']); + var $msg = PMA_ajaxShowMessage(); var $container = $(this); var callback = $('.callback', this).text(); // Perform the actual toggle diff --git a/js/messages.php b/js/messages.php index daed4742f5..96f759b186 100644 --- a/js/messages.php +++ b/js/messages.php @@ -214,6 +214,7 @@ $js_messages['strErrorProcessingRequest'] = __('Error in Processing Request'); $js_messages['strDroppingColumn'] = __('Dropping Column'); $js_messages['strAddingPrimaryKey'] = __('Adding Primary Key'); $js_messages['strOK'] = __('OK'); +$js_messages['strDismiss'] = __('Click to dismiss this notification'); /* For db_operations.js */ $js_messages['strRenamingDatabases'] = __('Renaming Databases'); diff --git a/js/rte/common.js b/js/rte/common.js index 85234590d7..842f3250ed 100644 --- a/js/rte/common.js +++ b/js/rte/common.js @@ -198,7 +198,7 @@ $(document).ready(function () { }); } } else { - PMA_ajaxShowMessage(data.error); + PMA_ajaxShowMessage(data.error, false); } }); // end $.post() } // end "if (RTE.validate())" @@ -245,7 +245,7 @@ $(document).ready(function () { // Execute item-specific code RTE.postDialogShow(data); } else { - PMA_ajaxShowMessage(data.error); + PMA_ajaxShowMessage(data.error, false); } }); // end $.get() }); // end $.live() @@ -301,7 +301,7 @@ $(document).ready(function () { var opts = {lineNumbers: true, matchBrackets: true, indentUnit: 4, mode: "text/x-mysql"}; CodeMirror.fromTextArea($elm[0], opts); } else { - PMA_ajaxShowMessage(data.error); + PMA_ajaxShowMessage(data.error, false); } }); // end $.get() }); // end $.live() @@ -370,7 +370,7 @@ $(document).ready(function () { // Show the query that we just executed PMA_slidingMessage(data.sql_query); } else { - PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error); + PMA_ajaxShowMessage(PMA_messages['strErrorProcessingRequest'] + " : " + data.error, false); } }); // end $.get() }); // end $.PMA_confirm() diff --git a/js/rte/routines.js b/js/rte/routines.js index ac7a291925..087b9d61a5 100644 --- a/js/rte/routines.js +++ b/js/rte/routines.js @@ -357,7 +357,7 @@ $(document).ready(function () { PMA_slidingMessage(data.message); $ajaxDialog.dialog('close'); } else { - PMA_ajaxShowMessage(data.error); + PMA_ajaxShowMessage(data.error, false); } }); }; @@ -388,7 +388,7 @@ $(document).ready(function () { PMA_slidingMessage(data.message); } } else { - PMA_ajaxShowMessage(data.error); + PMA_ajaxShowMessage(data.error, false); } }); // end $.get() }); // end $.live()