]> git.mxchange.org Git - mailer.git/blobdiff - js/ajax-common.js
Updated copyright notice as there are changes in this year
[mailer.git] / js / ajax-common.js
index 113864a9ee58b7b626fcba27c4034058b76bd9d6..69bd8a50c6f97d4cc0d479f8f9e5500e53c5bf1e 100644 (file)
@@ -7,7 +7,7 @@
  * $Author::                                                          $
  * --------------------------------------------------------------------
  * Copyright (c) 2003 - 2009 by Roland Haeder
- * Copyright (c) 2009 - 2012 by Mailer Developer Team
+ * Copyright (c) 2009 - 2013 by Mailer Developer Team
  * For more information visit: http://mxchange.org
  *
  * This program is free software; you can redistribute it and/or modify
 
 // Init variables
 var currentTabId       = null;
-var errorDisplayed     = false;
-var warningDisplayed   = false;
 var defaultTabId       = null;
 var footerElements     = new Array();
 var changedElements    = new Array();
+var data               = new Array();
 var formChanged        = false;
 var saveChangesId      = null;
 var lastErrorMessage   = null;
 var saveChangesPending = false;
 
+// Counter for success steps
+var counterSuccess = 0;
+
 // Add all footer navigation elements
 footerElements[0] = 'next';
 footerElements[1] = 'previous';
@@ -49,8 +51,34 @@ function setCurrentTabId (tabId) {
        currentTabId = tabId;
 }
 
+// Checks whether a given element is visible by checking 'display: none'
+function isElementVisible (prefix, element) {
+       // Get element
+       var el = document.getElementById(prefix + '_' + element);
+
+       // Is element set?
+       if ((el === null) || (el == undefined)) {
+               throw new '"' + prefix + '_' + element + '" does not exist.';
+       } else if ((el.style.display == undefined) || (el.style.display == '')) {
+               throw new '"' + prefix + '_' + element + '" has no style.display element.';
+       }
+
+       // Default is visible
+       var isVisible = (el.style.display != 'none');
+       //* DEBUG: */ alert(prefix + '_' + element + ':' + el.style.display + '=' + isVisible);
+
+       // Return status
+       return isVisible;
+}
+
 // Marks a tab navigation entry
 function markTabNavigation (prefix, tab) {
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Get all li-tags
        var li = document.getElementsByTagName('li');
 
@@ -100,30 +128,45 @@ function disableElement (element) {
 
 // Enables a given footer navigation element
 function enableFooterNavigationPage (element) {
-       // Remove the 'disabled' class and attribute
-       enableElement('input#' + element + '_page');
+       // Is it 'finish'?
+       if (element == 'finish') {
+               // Then without '_page' suffix
+               enableElement('input#finish');
+       } else {
+               // Regular element with '_page' suffix
+               enableElement('input#' + element + '_page');
+
+               // Disable 'finish' element
+               disableElement('input#finish');
+       }
 }
 
 // Resets footer navigation by adding CSS class 'disabled'
 function resetFooterNavigation () {
        // Remove the 'disabled' class and attribute
        for (var i = 0; i < footerElements.length; i++) {
-               $('input#' + footerElements[i] + '_page').addClass('disabled');
-               $('input#' + footerElements[i] + '_page').attr('disabled', 'disabled');
-               $('input#' + footerElements[i] + '_page').blur();
+               disableElement('input#' + footerElements[i] + '_page');
        } // END - for
+
+       // Disable this element
+       disableElement('input#finish');
 }
 
 // Getter for AJAX content
 function getAjaxContent () {
        // Is it defined?
-       if ($('body').data('ajax_content') == undefined) {
+       if (data['ajax_content'] == undefined) {
                // Not set
                throw new 'ajax_content requested but not set.';
        } // END - if
 
        // Return it
-       return $('body').data('ajax_content');
+       return data['ajax_content'];
+}
+
+// Setter for AJAX content
+function setAjaxContent (ajax_content) {
+       data['ajax_content'] = ajax_content;
 }
 
 // "Setter" for AJAX content but does decode the content
@@ -135,42 +178,32 @@ function setAjaxDecodedContent (ajax_content) {
        setAjaxContent(decoded);
 }
 
-// Setter for AJAX content
-function setAjaxContent (ajax_content) {
-       $('body').data('ajax_content', ajax_content);
-}
-
 // Getter for AJAX success
 function getAjaxSuccess () {
-       return $('body').data('ajax_success');
+       return data['ajax_success'];
 }
 
 // Setter for AJAX success
 function setAjaxSuccess (success) {
-       $('body').data('ajax_success', success);
+       data['ajax_success'] = success;
 }
 
 // Set AJAX reply and decode JSON if requested
 function setAjaxReply (reply, isJson) {
-       // Copy reply to local variable
-       var localReply = reply;
-
        // Is it JSON URL-encoded content?
-       if ((isJson != undefined) && (isJson == true)) {
-               // Then decode it, replace '%20' with space before because '%20' breakes JSON content
-               var obj = jQuery.parseJSON(reply.replace('%20', ' '));
+       //* DEBUG: */ alert('setAjaxReply(): reply=' + reply + ',isJson=' + isJson);
+       if ((isJson != undefined) && (isJson === true)) {
+               // Decode URL-encoding (for some reason it must be here ...)
+               var localReply = decodeUrlEncoding(reply);
 
-               // Is reply_content there
-               if (obj.reply_content == undefined) {
-                       // Not defined
-                       throw new 'obj.reply_content not returned from ajax.php, please fix your scripts.';
-               } // END - if
+               // Then decode it, replace '%20' with space before because '%20' breakes JSON content
+               var obj = jQuery.parseJSON(localReply.replace('%20', ' '));
 
                // ... and set it
-               setAjaxDecodedContent(obj.reply_content);
+               setAjaxContent(obj);
        } else {
                // Handle the content over to decode it
-               setAjaxDecodedContent(localReply);
+               setAjaxDecodedContent(reply);
        }
 }
 
@@ -189,16 +222,17 @@ function sendAjaxRequest (level, doValue, extra, isJson) {
                data: 'level=' + level + '&do=' + doValue + extra,
                dataType: 'json',
                async: false,
+               timeout: 10000,
 
                // Called on success
                success: function (ajax_content) {
                        // Is ajax_content set?
                        if (ajax_content.reply_content == undefined) {
                                // This shall not happen
-                               throw new 'ajax_content.reply_content not returned from ajax.php, please fix your scripts.';
-                       } else if (ajax_content.reply_content == null) {
+                               throw new 'ajax_content.reply_content not returned from ajax.php, please fix your scripts. (1)';
+                       } else if (ajax_content.reply_content === null) {
                                // This shall not happen, too
-                               throw new 'ajax_content.reply_content=null from ajax.php, please fix your scripts.';
+                               throw new 'ajax_content.reply_content=null from ajax.php, please fix your scripts. (2)';
                        }
 
                        // Set AJAX reply
@@ -212,11 +246,27 @@ function sendAjaxRequest (level, doValue, extra, isJson) {
                error: function (ajax_content) {
                        // Is ajax_content set?
                        if (ajax_content.reply_content == undefined) {
-                               // This shall not happen
-                               throw new 'ajax_content.reply_content not returned from ajax.php, please fix your scripts.';
-                       } else if (ajax_content.reply_content == null) {
+                               // Is 'responseText' there?
+                               if (ajax_content.responseText != undefined) {
+                                       // Then parse it
+                                       var obj = jQuery.parseJSON(ajax_content.responseText.replace('%20', ' '));
+
+                                       // Is 'reply_content' set?
+                                       if (obj.reply_content == undefined) {
+                                               // This shall not happen
+                                               throw new 'obj.reply_content not returned from ajax.php, please fix your scripts. (3)';
+                                       } // END - if
+
+                                       // Set it
+                                       setAjaxReply(obj.reply_content, false);
+                                       return false;
+                               } else {
+                                       // This shall not happen
+                                       throw new 'ajax_content.reply_content not returned from ajax.php, please fix your scripts. (4)';
+                               }
+                       } else if (ajax_content.reply_content === null) {
                                // This shall not happen, too
-                               throw new 'ajax_content.reply_content=null from ajax.php, please fix your scripts.';
+                               throw new 'ajax_content.reply_content=null from ajax.php, please fix your scripts. (5)';
                        }
 
                        // Set AJAX reply
@@ -225,16 +275,23 @@ function sendAjaxRequest (level, doValue, extra, isJson) {
        });
 
        // Return status
+       //* DEBUG: */ alert(getAjaxSuccess() + ':' + level + ',' + doValue + ',' + extra + ',' + isJson);
        return getAjaxSuccess();
 }
 
 // Enables footer navigation buttons
 function enableFooterNavigation (prefix, tabId) {
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Reset both footer navigation first
        resetFooterNavigation();
 
        // Do the AJAX request (JSON as content is enabled)
-       if (sendAjaxRequest(prefix, 'footer_navigation', '&tab=' + tabId, true) == true) {
+       if (sendAjaxRequest(prefix, 'footer_navigation', '&tab=' + tabId, true) === true) {
                // Parse the content
                $.each(getAjaxContent(), function (i, value) {
                        // Enable current element
@@ -248,12 +305,18 @@ function enableFooterNavigation (prefix, tabId) {
 
 // Requests an AJAX content
 function requestAjaxContent (prefix, htmlId, tabId, footerNavigation) {
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Check if this request is disabled
        if ($('#' + prefix + '_' + tabId).hasClass('tab_disabled')) {
                // Clicked on a disabled tabId so blur it
                //* DEBUG: */ alert('requestAjaxContent(): prefix=' + prefix + ',htmlId=' + htmlId + ',tabId=' + tabId + ' - DISABLED!');
                return;
-       } else if (formChanged == true) {
+       } else if (formChanged === true) {
                // Has changed form , so output message to browser
                //* DEBUG: */ alert('requestAjaxContent(): prefix=' + prefix + ',htmlId=' + htmlId + ',tabId=' + tabId + ' - FORM CHANGED!');
                displayChangedWarningWindow(prefix, tabId);
@@ -272,7 +335,7 @@ function requestAjaxContent (prefix, htmlId, tabId, footerNavigation) {
                // Fade the old content out
                $('#' + htmlId).fadeOut('fast', function() {
                        // Send AJAX request
-                       if (sendAjaxRequest(prefix, 'request_content', '&tab=' + tabId, true) == true) {
+                       if (sendAjaxRequest(prefix, 'request_content', '&tab=' + tabId, false) === true) {
                                // Add the HTML content
                                $('#' + htmlId).html(getAjaxContent());
 
@@ -282,7 +345,7 @@ function requestAjaxContent (prefix, htmlId, tabId, footerNavigation) {
                                        markTabNavigation(prefix, tabId);
 
                                        // Is the footer navigation enabled?
-                                       if (footerNavigation == true) {
+                                       if (footerNavigation === true) {
                                                // Change footer navigation as well
                                                enableFooterNavigation(prefix, tabId);
                                        } // END - if
@@ -303,60 +366,59 @@ function displayTestWindow (prefix, element) {
        // Register click-event for error window
        $('#' + prefix + '_error_close').click(function () {
                // Close the window
-               closeErrorWindow(prefix);
+               closeErrorWindow(prefix, true, false);
        });
 
        // Register click-event for warning window
        $('#' + prefix + '_warning_close').click(function () {
                // Close the window
                //* DEBUG: */ alert('displayTestWindow(): prefix=' + prefix + ' - calling closeWarningWindow()');
-               closeWarningWindow(prefix);
+               closeWarningWindow(prefix, true, false);
        });
 
        // Request it from the AJAX backend
-       if (sendAjaxRequest(prefix, 'test', ''== true) {
+       if (sendAjaxRequest(prefix, 'test', '', false) === true) {
                // Transfer the returned content to the prefix_warning_content id
-               $('#' + prefix + '_warning_content').html(getAjaxContent());
+               setWarningContent(prefix, getAjaxContent());
 
                // Fade the warning in
                $('#' + prefix + '_warning').fadeIn('slow', function() {
                        // Enable element
                        enableElement(element);
                });
-
-               // Mark 'warning' as displayed
-               warningDisplayed = true;
        } else {
                // Display error message
                displayErrorWindow(prefix, getAjaxContent());
        }
 }
 
+// Fades slowly in given window
+function fadeInWindow (prefix, id) {
+       // Do the fade-in
+       $('#' + prefix + '_' + id).fadeIn('slow', function() {
+               // Do nothing for now
+       });
+}
+
 // Displays a warning window above the form to warn about changed&unsafed fields
 function displayChangedWarningWindow (prefix, button) {
-       // Fade out warning window, if open
        //* DEBUG: */ alert('displayChangedWarningWindow(): prefix=' + prefix + ',button=' + button + ' - calling closeWarningWindow()');
-       closeWarningWindow(prefix);
-
-       // Fade error out for eye-candy, if open
-       closeErrorWindow(prefix);
+       // Fade all windows out
+       closeAllWindows(prefix);
 
        // Abort here if warningDisplayed is still true
-       if (warningDisplayed == true) {
+       if (isElementVisible(prefix, 'warning')) {
                // Make sure this doesn't happen
                return;
        } // END - if
 
        // Request it from the AJAX backend
-       if (sendAjaxRequest(prefix, 'change_warning', '&button=' + button + '&elements=' + changedElements.join(':')) == true) {
+       if (sendAjaxRequest(prefix, 'change_warning', '&button=' + button + '&elements=' + changedElements.join(':')) === true) {
                // Transfer the returned content to the prefix_warning_content id
-               $('#' + prefix + '_warning_content').html(getAjaxContent());
+               setWarningContent(prefix, getAjaxContent());
 
                // Fade the warning in
-               $('#' + prefix + '_warning').fadeIn('slow', function() {
-                       // Mark warning as displayed
-                       warningDisplayed = true;
-               });
+               fadeInWindow(prefix, 'warning');
        } else {
                // Display error message
                displayErrorWindow(prefix, getAjaxContent());
@@ -365,51 +427,125 @@ function displayChangedWarningWindow (prefix, button) {
 
 // Displays the error window for given prefix and content
 function displayErrorWindow (prefix, ajax_content) {
-       // Fade out warning window, if open
-       //* DEBUG: */ alert('displayErrorWindow(): prefix=' + prefix + ' - calling closeWarningWindow()');
-       closeWarningWindow(prefix);
-
-       // Fade it out for eye-candy
-       closeErrorWindow(prefix);
+       //* DEBUG: */ alert('displayErrorWindow(): prefix=' + prefix + ',ajax_content=' + ajax_content + ' - calling closeWarningWindow()');
+       // Fade all windows out
+       closeAllWindows(prefix);
 
        // Abort here if errorDisplayed is still true
-       if (errorDisplayed == true) {
+       if (isElementVisible(prefix, 'error')) {
                // Make sure this doesn't happen
                return;
        } // END - if
 
        // Copy the response text to the error variable
        if (ajax_content.reply_content != undefined) {
-               $('#' + prefix + '_error_content').html(ajax_content.reply_content);
+               setErrorContent(prefix, ajax_content.reply_content);
        } else {
-               $('#' + prefix + '_error_content').html(ajax_content);
+               setErrorContent(prefix, ajax_content);
        }
 
        // Fade the error in
-       $('#' + prefix + '_error').fadeIn('slow', function() {
-               // Mark error as displayed
-               errorDisplayed = true;
-       });
+       fadeInWindow(prefix, 'error');
+}
+
+// Displays the progress window for given prefix and content
+function displayProgressWindow (prefix, ajax_content) {
+       //* DEBUG: */ alert('displayProgressWindow(): prefix=' + prefix + ' - calling closeWarningWindow()');
+       // Fade all windows out
+       closeAllWindows(prefix);
+
+       // Abort here if progressDisplayed is still true
+       if (isElementVisible(prefix, 'progress')) {
+               // Make sure this doesn't happen
+               return;
+       } // END - if
+
+       // Copy the response text to the progress variable
+       if (ajax_content.reply_content != undefined) {
+               // Set HTML content
+               setProgressContent(prefix, ajax_content.reply_content);
+       } else {
+               setProgressContent(prefix, ajax_content);
+       }
+
+       // Fade the progress in
+       fadeInWindow(prefix, 'progress');
+}
+
+// Displays the success window for given prefix and content
+function displaySuccessWindow (prefix, ajax_content) {
+       //* DEBUG: */ alert('displaySuccessWindow(): prefix=' + prefix + ' - calling closeWarningWindow()');
+       // Fade all windows out
+       closeAllWindows(prefix);
+
+       // Abort here if successDisplayed is still true
+       if (isElementVisible(prefix, 'success')) {
+               // Make sure this doesn't happen
+               return;
+       } // END - if
+
+       // Copy the response text to the success variable
+       if (ajax_content.reply_content != undefined) {
+               // Set HTML content
+               setSuccessContent(prefix, ajax_content.reply_content);
+       } else {
+               setSuccessContent(prefix, ajax_content);
+       }
+
+       // Fade the success in
+       fadeInWindow(prefix, 'success');
+}
+
+// Sets "warning content"
+function setWarningContent (prefix, content) {
+       // Set HTML content
+       $('#' + prefix + '_warning_content').html(content);
+}
+
+// Sets "error content"
+function setErrorContent (prefix, content) {
+       // Set HTML content
+       $('#' + prefix + '_error_content').html(content);
+}
+
+// Sets "progress content"
+function setProgressContent (prefix, content) {
+       // Set HTML content
+       $('#' + prefix + '_progress_content').html(content);
+}
+
+// Sets "success content"
+function setSuccessContent (prefix, content) {
+       // Set HTML content
+       $('#' + prefix + '_success_content').html(content);
+}
+
+// Close all windows
+function closeAllWindows (prefix) {
+       closeWarningWindow(prefix, true, false);
+       closeErrorWindow(prefix, true, false);
+       closeProgressWindow(prefix, true, false);
+       closeSuccessWindow(prefix, true, false);
 }
 
 // Waits until the window has been closed
-function closeErrorLocked () {
+function closeErrorLocked (prefix) {
        // Has all been loaded?
-       if (errorDisplayed == false) {
+       if (!isElementVisible(prefix, 'error')) {
                // Then release ready()
                $.holdReady(false);
        } else {
                // Recursive call again
-               window.setTimeout('closeErrorLocked()', 10);
+               window.setTimeout('closeErrorLocked("' + prefix + '")', 10);
        }
 }
 
 // Closes an error window
 function closeErrorWindow (prefix, waitClose, resetCurrentTabId) {
        // Is the error displayed?
-       if (errorDisplayed == true) {
+       if (isElementVisible(prefix, 'error')) {
                // Shall we wait ("sync") until the animation has completed?
-               if (waitClose == true) {
+               if (waitClose === true) {
                        // Hold the ready status
                        $.holdReady(true);
                } // END - if
@@ -417,31 +553,104 @@ function closeErrorWindow (prefix, waitClose, resetCurrentTabId) {
                // Yes, then fade it out
                $('#' + prefix + '_error').fadeOut('fast', function() {
                        // Set current tab id to default
-                       if (resetCurrentTabId == true) {
+                       if (resetCurrentTabId === true) {
+                               setCurrentTabId(defaultTabId);
+                       } // END - if
+               });
+
+               // Shall this animation be "synchronized"?
+               if (waitClose === true) {
+                       // Wait for the window has been closed
+                       closeErrorLocked(prefix);
+               } // END - if
+       } // END - if
+}
+
+// Waits until the window has been closed
+function closeProgressLocked (prefix) {
+       // Has all been loaded?
+       if (!isElementVisible(prefix, 'progress')) {
+               // Then release ready()
+               $.holdReady(false);
+       } else {
+               // Recursive call again
+               window.setTimeout('closeProgressLocked("' + prefix + '")', 10);
+       }
+}
+
+// Closes an progress window
+function closeProgressWindow (prefix, waitClose, resetCurrentTabId) {
+       // Is the progress displayed?
+       if (isElementVisible(prefix, 'progress')) {
+               // Shall we wait ("sync") until the animation has completed?
+               if (waitClose === true) {
+                       // Hold the ready status
+                       $.holdReady(true);
+               } // END - if
+
+               // Yes, then fade it out
+               $('#' + prefix + '_progress').fadeOut('fast', function() {
+                       // Set current tab id to default
+                       if (resetCurrentTabId === true) {
                                setCurrentTabId(defaultTabId);
                        } // END - if
+               });
+
+               // Shall this animation be "synchronized"?
+               if (waitClose === true) {
+                       // Wait for the window has been closed
+                       closeProgressLocked(prefix);
+               } // END - if
+       } // END - if
+}
+
+// Waits until the window has been closed
+function closeSuccessLocked (prefix) {
+       // Has all been loaded?
+       if (!isElementVisible(prefix, 'success')) {
+               // Then release ready()
+               $.holdReady(false);
+       } else {
+               // Recursive call again
+               window.setTimeout('closeSuccessLocked("' + prefix + '")', 10);
+       }
+}
 
-                       // Mark it as closed
-                       errorDisplayed = false;
+// Closes an success window
+function closeSuccessWindow (prefix, waitClose, resetCurrentTabId) {
+       // Is the success displayed?
+       if (isElementVisible(prefix, 'success')) {
+               // Shall we wait ("sync") until the animation has completed?
+               if (waitClose === true) {
+                       // Hold the ready status
+                       $.holdReady(true);
+               } // END - if
+
+               // Yes, then fade it out
+               $('#' + prefix + '_success').fadeOut('fast', function() {
+                       // Set current tab id to default
+                       if (resetCurrentTabId === true) {
+                               setCurrentTabId(defaultTabId);
+                       } // END - if
                });
 
                // Shall this animation be "synchronized"?
-               if (waitClose == true) {
+               if (waitClose === true) {
                        // Wait for the window has been closed
-                       closeErrorLocked();
+                       closeSuccessLocked(prefix);
                } // END - if
        } // END - if
 }
 
 // Waits until the window has been closed
-function closeWarningLocked () {
+function closeWarningLocked (prefix) {
        // Has all been loaded?
-       if (warningDisplayed == false) {
+       if (!isElementVisible(prefix, 'warning')) {
                // Then release ready()
                $.holdReady(false);
        } else {
                // Recursive call again
-               window.setTimeout('closeWarningLocked()', 10);
+               window.setTimeout('closeWarningLocked("' + prefix + '")', 10);
        }
 }
 
@@ -449,10 +658,10 @@ function closeWarningLocked () {
 function closeWarningWindow (prefix, waitClose, resetCurrentTabId) {
        //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ' - ENTERED!');
        // Is the warning displayed?
-       if (warningDisplayed == true) {
+       if (isElementVisible(prefix, 'warning')) {
                // Shall we wait ("sync") until the animation has completed?
                //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ',warningDisplayed=true');
-               if (waitClose == true) {
+               if (waitClose === true) {
                        // Hold the ready status
                        $.holdReady(true);
                } // END - if
@@ -460,21 +669,16 @@ function closeWarningWindow (prefix, waitClose, resetCurrentTabId) {
                // Yes, then fade it out
                $('#' + prefix + '_warning').fadeOut('fast', function() {
                        // Set current tab id to default
-                       //* DEBUG: */ alert('closeWarningWindow(): prefix=' + prefix + ',waitClose=' + waitClose + ',defaultTab=' + defaultTabId + ' - Calling setCurrentTabId()');
-                       if (resetCurrentTabId == true) {
+                       if (resetCurrentTabId === true) {
                                setCurrentTabId(defaultTabId);
                        } // END - if
-
-                       // Mark it as closed
-                       warningDisplayed = false;
-                       //* DEBUG: */ alert('closeWarningWindow(): waitClose=' + waitClose + ',resetCurrentTabId=' + resetCurrentTabId + ',warningDisplayed=false');
                });
 
                // Shall this animation be "synchronized"?
-               if (waitClose == true) {
+               if (waitClose === true) {
                        // Wait for the window has been closed
                        //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ' - LOCKED!');
-                       closeWarningLocked();
+                       closeWarningLocked(prefix);
                } // END - if
        } // END - if
 }
@@ -483,7 +687,7 @@ function closeWarningWindow (prefix, waitClose, resetCurrentTabId) {
 function doFooterPage (prefix, htmlId, button) {
        //* DEBUG: */ alert('doFooterPage(): prefix=' + prefix + ',htmlId=' + htmlId + ',button=' + button + ' - ENTERED!');
        // Has something being changed?
-       if (formChanged == true) {
+       if (formChanged === true) {
                // Output message to browser
                displayChangedWarningWindow(prefix, button);
 
@@ -491,15 +695,27 @@ function doFooterPage (prefix, htmlId, button) {
                return;
        } // END - if
 
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Is there a 'next' entry?
        //* DEBUG: */ alert('doFooterPage(): button=' + button + ',currentTabId=' + currentTabId + ',nextPage[currentTabId]=' + nextPage[currentTabId]);
-       if ((button == 'next') && (nextPage[currentTabId] != null)) {
+       if ((button == 'next') && (nextPage[currentTabId] !== null)) {
                // Then call the AJAX requester
-               requestAjaxContent(prefix, htmlId, nextPage[currentTabId]);
-       } else if ((button == 'previous') && (previousPage[currentTabId] != null)) {
+               var page = nextPage[currentTabId];
+       } else if ((button == 'previous') && (previousPage[currentTabId] !== null)) {
                // Then call the AJAX requester
-               requestAjaxContent(prefix, htmlId, previousPage[currentTabId]);
+               var page = previousPage[currentTabId];
        }
+
+       // Request AJAX content
+       requestAjaxContent(prefix, htmlId, page);
+
+       // Change the footer navigation
+       enableFooterNavigation(prefix, page);
 }
 
 // Allows to save made changes (this will be called if the onchange event has been triggered)
@@ -563,8 +779,8 @@ function markFormFieldsFailed (failedFields) {
        });
 }
 
-// Processes the content from AJAX call
-function processAjaxResponseContent (prefix, ajax_content) {
+// Progresses the content from AJAX call
+function progressAjaxResponseContent (prefix, ajax_content) {
        // By default all is failed
        var isResponseDone = false;
 
@@ -589,6 +805,12 @@ function processAjaxResponseContent (prefix, ajax_content) {
 
 // Saves changes by sending the data to the AJAX backend script
 function saveChanges (prefix) {
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Mark all elements as unchanged
        markAllElementsAsUnchanged();
 
@@ -596,7 +818,7 @@ function saveChanges (prefix) {
        if (changedElements.length == 0) {
                // This should not happen
                displayErrorWindow(prefix, '<div class="ajax_error_message">saveChanges() called with no changed elements.</div>');
-       } else if (saveChangesId == null) {
+       } else if (saveChangesId === null) {
                // saveChangesId is not det
                displayErrorWindow(prefix, '<div class="ajax_error_message">saveChangesId is not set. Please add <em>saveChanges = \'foo_bar\';</em> to your code.</div>');
        }
@@ -612,12 +834,12 @@ function saveChanges (prefix) {
         * Send the request to the AJAX backend, it doesn't matter from which page
         * this was requested.
         */
-       if (sendAjaxRequest(prefix, 'save_changes', '&tab=' + currentTabId + '&' + serializedData, true) == true) {
+       if (sendAjaxRequest(prefix, 'save_changes', '&tab=' + currentTabId + '&' + serializedData, true) === true) {
                // Get the content
                var ajax_content = getAjaxContent();
 
-               // Process the returned content
-               if (processAjaxResponseContent(prefix, ajax_content) == true) {
+               // Progress the returned content
+               if (progressAjaxResponseContent(prefix, ajax_content) === true) {
                        // Mark all elements as unchanged
                        markAllElementsAsUnchanged();
 
@@ -633,7 +855,7 @@ function saveChanges (prefix) {
                                displayErrorWindow(prefix, '<div class="ajax_error_message">' + ajax_content.message + '</div>');
                        } else {
                                // This didn't work, why?
-                               displayErrorWindow(prefix, '<div class="ajax_error_message">processAjaxResponseContent() failed, please fix this.<br />\n' + lastErrorMessage + '</div>');
+                               displayErrorWindow(prefix, '<div class="ajax_error_message">progressAjaxResponseContent() failed, please fix this.<br />\n' + lastErrorMessage + '</div>');
                        }
                }
 
@@ -657,7 +879,7 @@ function saveChanges (prefix) {
 // Waiting for resources being loaded
 function saveChangesLocked () {
        // Has all been loaded?
-       if (saveChangesPending == false) {
+       if (saveChangesPending === false) {
                // Then release ready()
                $.holdReady(false);
        } else {
@@ -681,6 +903,12 @@ function doSaveChangesPage (prefix, htmlId, page) {
 
 // Saves changed settings and continues with given tab
 function doSaveChangesContinue (prefix, htmlId, tab) {
+       // Is progress working?
+       if (isElementVisible(prefix, 'progress')) {
+               // Then exit silently
+               return;
+       } // END - if
+
        // Save the changes
        saveChanges(prefix);
 
@@ -691,3 +919,72 @@ function doSaveChangesContinue (prefix, htmlId, tab) {
        // Load requested content
        requestAjaxContent(prefix, htmlId, tab);
 }
+
+// Registers common things (close button, drap&drop)
+function registerCommons (prefix) {
+       //-----------------------------------------
+       //             Close buttons
+       //-----------------------------------------
+       $('#' + prefix + '_error_close').click(function () {
+               // Close the window
+               closeErrorWindow(prefix);
+       });
+
+       $('#' + prefix + '_warning_close').click(function () {
+               // Close the window
+               closeWarningWindow(prefix);
+       });
+
+       $('#' + prefix + '_success_close').click(function () {
+               // Close the window
+               closeSuccessWindow(prefix);
+       });
+
+       //-----------------------------------------
+       //              Drag'N'Drop
+       //-----------------------------------------
+       $('#' + prefix + '_progress').draggable({
+               opacity: 0.85
+       });
+
+       $('#' + prefix + '_warning').draggable({
+               opacity: 0.85
+       });
+
+       $('#' + prefix + '_success').draggable({
+               opacity: 0.85
+       });
+
+       $('#' + prefix + '_error').draggable({
+               opacity: 0.85
+       });
+}
+
+// Update progress bar
+function updateProgressBar (maxValue) {
+       // Increment counter
+       counterSuccess++;
+
+       // Do only update <= 100% values
+       if (counterSuccess <= maxValue) {
+               // Update progress bar
+               $('#progressbar').progressbar({
+                       value: (counterSuccess / maxValue * 100)
+               });
+       } // END - if
+}
+
+// Updates a given "status" field
+function updateStatusField (id, cssClass, statusMessage) {
+       // Set message
+       $('#' + id).html(statusMessage);
+
+       // Is a cssClass set?
+       if (cssClass != '') {
+               // Add it
+               $('#' + id).addClass(cssClass);
+       } else {
+               // Remove all classes
+               $('#' + id).removeClass();
+       }
+}