--- /dev/null
+/**
+ * Common JavaScript functions for AJAX requests (they are general purpose).
+ * --------------------------------------------------------------------
+ * $Revision:: $
+ * $Date:: $
+ * $Tag:: 0.2.1-FINAL $
+ * $Author:: $
+ * --------------------------------------------------------------------
+ * Copyright (c) 2003 - 2009 by Roland Haeder
+ * Copyright (c) 2009 - 2012 by Mailer Developer Team
+ * For more information visit: http://mxchange.org
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+// Init variables
+var currentTabId = null;
+var errorDisplayed = false;
+var warningDisplayed = false;
+var defaultTabId = null;
+var footerElements = new Array();
+var changedElements = new Array();
+var formChanged = false;
+var saveChangesId = null;
+var lastErrorMessage = null;
+var saveChangesPending = false;
+
+// Add all footer navigation elements
+footerElements[0] = 'next';
+footerElements[1] = 'previous';
+
+// Setter for current tab id
+function setCurrentTabId (tabId) {
+ // Set it
+ //* DEBUG: */ alert('currentTabId=' + currentTabId + ',tabId=' + tabId);
+ currentTabId = tabId;
+}
+
+// Marks a tab navigation entry
+function markTabNavigation (prefix, tab) {
+ // Get all li-tags
+ var li = document.getElementsByTagName('li');
+
+ // Set current tab name
+ var currentTabName = 'tab_enabled';
+
+ // Set tab name
+ var tabName = prefix + '_' + tab;
+
+ // Search for all menus
+ for (var i = 0; i < li.length; i++) {
+ // Debug message
+ //* DEBUG: */ document.write('className=' + li[i].className + ',prefix=' + prefix + ',tab=' + tab + '<br />');
+
+ // Check for valid tab
+ if (li[i].className.substr(0, currentTabName.length) == currentTabName) {
+ // Okay does match (don't change any others)
+ if (li[i].id == tabName) {
+ // Mark this menu
+ $('li#' + tabName).addClass('tab_active');
+ //li[i].className += ' tab_active';
+ } else {
+ // Unmark this menu
+ $('li#' + li[i].id).removeClass('tab_active');
+ //li[i].className = currentTabName;
+ }
+ } // END - if
+ } // END - for
+}
+
+// Enables a given element
+function enableElement (element) {
+ // Remove class and attribute
+ $(element).removeClass('disabled');
+ $(element).removeAttr('disabled');
+}
+
+// Disables a given element
+function disableElement (element) {
+ // Add class and attribute
+ $(element).addClass('disabled');
+ $(element).attr('disabled', 'disabled');
+
+ // Blur the element
+ $(element).blur();
+}
+
+// Enables a given footer navigation element
+function enableFooterNavigationPage (element) {
+ // Remove the 'disabled' class and attribute
+ enableElement('input#' + element + '_page');
+}
+
+// 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();
+ } // END - for
+}
+
+// Getter for AJAX content
+function getAjaxContent () {
+ // Is it defined?
+ if ($('body').data('ajax_content') == undefined) {
+ // Not set
+ throw new 'ajax_content requested but not set.';
+ } // END - if
+
+ // Return it
+ return $('body').data('ajax_content');
+}
+
+// "Setter" for AJAX content but does decode the content
+function setAjaxDecodedContent (ajax_content) {
+ // Decode URL-encoded data ...
+ var decoded = decodeUrlEncoding(ajax_content);
+
+ // ... and set it
+ 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');
+}
+
+// Setter for AJAX success
+function setAjaxSuccess (success) {
+ $('body').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', ' '));
+
+ // 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
+
+ // ... and set it
+ setAjaxDecodedContent(obj.reply_content);
+ } else {
+ // Handle the content over to decode it
+ setAjaxDecodedContent(localReply);
+ }
+}
+
+// Sends out an AJAX request
+function sendAjaxRequest (level, doValue, extra, isJson) {
+ // By default all requests failed
+ setAjaxSuccess(false);
+
+ // Reset AJAX content
+ setAjaxContent('');
+
+ // Send out the raw request
+ $.ajax({
+ url: 'ajax.php',
+ type: 'POST',
+ data: 'level=' + level + '&do=' + doValue + extra,
+ dataType: 'json',
+ async: false,
+
+ // Called on success
+ success: function (ajax_content) {
+ // Is ajax_content set?
+ if (ajax_content.responseText == undefined) {
+ // This shall not happen
+ throw new 'ajax_content.responseText not returned from ajax.php, please fix your scripts.';
+ } else if (ajax_content.responseText == null) {
+ // This shall not happen, too
+ throw new 'ajax_content.responseText=null from ajax.php, please fix your scripts.';
+ }
+
+ // Set AJAX reply
+ setAjaxReply(ajax_content.responseText, isJson);
+
+ // Mark it as success
+ setAjaxSuccess(true);
+ },
+
+ // Called in case of an error (e.g. HTTP response status not '200 OK')
+ error: function (ajax_content) {
+ // Is ajax_content set?
+ if (ajax_content.responseText == undefined) {
+ // This shall not happen
+ throw new 'ajax_content.responseText not returned from ajax.php, please fix your scripts.';
+ } else if (ajax_content.responseText == null) {
+ // This shall not happen, too
+ throw new 'ajax_content.responseText=null from ajax.php, please fix your scripts.';
+ }
+
+ // Set AJAX reply
+ setAjaxReply(ajax_content.responseText, isJson);
+ }
+ });
+
+ // Return status
+ return getAjaxSuccess();
+}
+
+// Enables footer navigation buttons
+function enableFooterNavigation (prefix, tabId) {
+ // Reset both footer navigation first
+ resetFooterNavigation();
+
+ // Do the AJAX request (JSON as content is enabled)
+ if (sendAjaxRequest(prefix, 'footer_navigation', '&tab=' + tabId, true) == true) {
+ // Parse the content
+ $.each(getAjaxContent(), function (i, value) {
+ // Enable current element
+ enableFooterNavigationPage(value);
+ });
+ } else {
+ // Display error window
+ displayErrorWindow(prefix, getAjaxContent());
+ }
+}
+
+// Requests an AJAX content
+function requestAjaxContent (prefix, htmlId, tabId, footerNavigation) {
+ // 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) {
+ // Has changed form , so output message to browser
+ //* DEBUG: */ alert('requestAjaxContent(): prefix=' + prefix + ',htmlId=' + htmlId + ',tabId=' + tabId + ' - FORM CHANGED!');
+ displayChangedWarningWindow(prefix, tabId);
+
+ // Abort here
+ return;
+ }
+
+ // Only request if content is different
+ //* DEBUG: */ alert('requestAjaxContent(): prefix=' + prefix + ',htmlId=' + htmlId + ',tabId=' + tabId + ',currentTabId=' + currentTabId);
+ if (tabId != currentTabId) {
+ // Set tabId as current
+ //* DEBUG: */ alert('requestAjaxContent(): prefix=' + prefix + ',htmlId=' + htmlId + ',tabId=' + tabId + ' - Calling setCurrentTabId()');
+ setCurrentTabId(tabId);
+
+ // Fade the old content out
+ $('#' + htmlId).fadeOut('fast', function() {
+ // Send AJAX request
+ if (sendAjaxRequest(prefix, 'request_content', '&tab=' + tabId, true) == true) {
+ // Add the HTML content
+ $('#' + htmlId).html(getAjaxContent());
+
+ // Fade the content in
+ $('#' + htmlId).fadeIn('fast', function() {
+ // This differs, so mark the menu and request content
+ markTabNavigation(prefix, tabId);
+
+ // Is the footer navigation enabled?
+ if (footerNavigation == true) {
+ // Change footer navigation as well
+ enableFooterNavigation(prefix, tabId);
+ } // END - if
+ });
+ } else {
+ // Display error window
+ displayErrorWindow(prefix, getAjaxContent());
+ }
+ });
+ } else {
+ // Same id
+ //* DEBUG: */ alert('SAME!');
+ }
+}
+
+// Displays a test window
+function displayTestWindow (prefix, element) {
+ // Register click-event for error window
+ $('#' + prefix + '_error_close').click(function () {
+ // Close the window
+ closeErrorWindow(prefix);
+ });
+
+ // Register click-event for warning window
+ $('#' + prefix + '_warning_close').click(function () {
+ // Close the window
+ //* DEBUG: */ alert('displayTestWindow(): prefix=' + prefix + ' - calling closeWarningWindow()');
+ closeWarningWindow(prefix);
+ });
+
+ // Request it from the AJAX backend
+ if (sendAjaxRequest(prefix, 'test', '') == true) {
+ // Transfer the returned content to the prefix_warning_content id
+ $('#' + prefix + '_warning_content').html(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());
+ }
+}
+
+// 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);
+
+ // Abort here if warningDisplayed is still true
+ if (warningDisplayed == true) {
+ // 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) {
+ // Transfer the returned content to the prefix_warning_content id
+ $('#' + prefix + '_warning_content').html(getAjaxContent());
+
+ // Fade the warning in
+ $('#' + prefix + '_warning').fadeIn('slow', function() {
+ // Mark warning as displayed
+ warningDisplayed = true;
+ });
+ } else {
+ // Display error message
+ displayErrorWindow(prefix, getAjaxContent());
+ }
+}
+
+// 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);
+
+ // Abort here if errorDisplayed is still true
+ if (errorDisplayed == true) {
+ // Make sure this doesn't happen
+ return;
+ } // END - if
+
+ // Copy the response text to the error variable
+ if (ajax_content.responseText != undefined) {
+ $('#' + prefix + '_error_content').html(ajax_content.responseText);
+ } else {
+ $('#' + prefix + '_error_content').html(ajax_content);
+ }
+
+ // Fade the error in
+ $('#' + prefix + '_error').fadeIn('slow', function() {
+ // Mark error as displayed
+ errorDisplayed = true;
+ });
+}
+
+// Waits until the window has been closed
+function closeErrorLocked () {
+ // Has all been loaded?
+ if (errorDisplayed == false) {
+ // Then release ready()
+ $.holdReady(false);
+ } else {
+ // Recursive call again
+ window.setTimeout('closeErrorLocked()', 10);
+ }
+}
+
+// Closes an error window
+function closeErrorWindow (prefix, waitClose, resetCurrentTabId) {
+ // Is the error displayed?
+ if (errorDisplayed == true) {
+ // 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 + '_error').fadeOut('fast', function() {
+ // Set current tab id to default
+ if (resetCurrentTabId == true) {
+ setCurrentTabId(defaultTabId);
+ } // END - if
+
+ // Mark it as closed
+ errorDisplayed = false;
+ });
+
+ // Shall this animation be "synchronized"?
+ if (waitClose == true) {
+ // Wait for the window has been closed
+ closeErrorLocked();
+ } // END - if
+ } // END - if
+}
+
+// Waits until the window has been closed
+function closeWarningLocked () {
+ // Has all been loaded?
+ if (warningDisplayed == false) {
+ // Then release ready()
+ $.holdReady(false);
+ } else {
+ // Recursive call again
+ window.setTimeout('closeWarningLocked()', 10);
+ }
+}
+
+// Closes an warning window
+function closeWarningWindow (prefix, waitClose, resetCurrentTabId) {
+ //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ' - ENTERED!');
+ // Is the warning displayed?
+ if (warningDisplayed == true) {
+ // Shall we wait ("sync") until the animation has completed?
+ //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ',warningDisplayed=true');
+ if (waitClose == true) {
+ // Hold the ready status
+ $.holdReady(true);
+ } // END - if
+
+ // 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) {
+ 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) {
+ // Wait for the window has been closed
+ //* DEBUG: */ alert('prefix=' + prefix + ',waitClose=' + waitClose + ' - LOCKED!');
+ closeWarningLocked();
+ } // END - if
+ } // END - if
+}
+
+// A footer navigation button has been clicked
+function doFooterPage (prefix, htmlId, button) {
+ //* DEBUG: */ alert('doFooterPage(): prefix=' + prefix + ',htmlId=' + htmlId + ',button=' + button + ' - ENTERED!');
+ // Has something being changed?
+ if (formChanged == true) {
+ // Output message to browser
+ displayChangedWarningWindow(prefix, button);
+
+ // Abort here
+ return;
+ } // END - if
+
+ // Do we have a 'next' entry?
+ //* DEBUG: */ alert('doFooterPage(): button=' + button + ',currentTabId=' + currentTabId + ',nextPage[currentTabId]=' + nextPage[currentTabId]);
+ if ((button == 'next') && (nextPage[currentTabId] != null)) {
+ // Then call the AJAX requester
+ requestAjaxContent(prefix, htmlId, nextPage[currentTabId]);
+ } else if ((button == 'previous') && (previousPage[currentTabId] != null)) {
+ // Then call the AJAX requester
+ requestAjaxContent(prefix, htmlId, previousPage[currentTabId]);
+ }
+}
+
+// Allows to save made changes (this will be called if the onchange event has been triggered)
+function allowSaveChanges (element) {
+ // Mark element as changed, unmark as failed
+ $('#' + element).addClass('field_changed');
+ $('#' + element).removeClass('field_failed');
+
+ // Is the element not there?
+ if (!in_array(element, changedElements)) {
+ // Mark the form as changed
+ formChanged = true;
+
+ // Make the 'Save changes' button clickable
+ enableElement('#' + saveChangesId);
+
+ // Remember this for later AJAX call
+ changedElements.push(element);
+ } // END - if
+}
+
+// Marks all elements as unchanged/not failed
+function markAllElementsAsUnchanged () {
+ // Remove status from all fields
+ for (var i = 0; i < changedElements.length; i++) {
+ // Mark the element as changed
+ $('#' + changedElements[i]).removeClass('field_changed');
+ $('#' + changedElements[i]).removeClass('field_failed');
+ } // END - for
+}
+
+// Function to reset the form
+function resetMailerAjaxForm () {
+ // Debug message
+ //* DEBUG: */ alert('resetMailerAjaxForm(): changedElements()=' + changedElements.length + ',saveChangesId=' + saveChangesId + ' - ENTERED!');
+
+ // Mark all elements as unchanged
+ markAllElementsAsUnchanged();
+
+ // Clear all changed elements
+ disableElement('input#' + saveChangesId);
+
+ // Reset changed elements and mark form as not changed
+ changedElements = new Array();
+ formChanged = false;
+}
+
+// Mark given fields as failed
+function markFormFieldsFailed (failedFields) {
+ // Mark all elements as failed
+ $.each(failedFields, function (i, field) {
+ // Mark the element as 'failed'
+ $('#' + field).removeClass('field_changed');
+ $('#' + field).addClass('field_failed');
+
+ // Also register it as 'changed', if not found
+ if (!in_array(field, changedElements)) {
+ // Okay, not yet added, so push it on the array
+ changedElements.push(field);
+ } // END - if
+ });
+}
+
+// Processes the content from AJAX call
+function processAjaxResponseContent (prefix, ajax_content) {
+ // By default all is failed
+ var isResponseDone = false;
+
+ // Is 'status' and 'message' set?
+ if ((ajax_content.status == undefined) || (ajax_content.message == undefined)) {
+ // No status/message set
+ lastErrorMessage = 'Returned content does not provide $status$ or $message$ which is required.';
+ } else if ((ajax_content.status != 'done') && (ajax_content.status != 'failed')) {
+ // This is also not good, only 'failed' or 'done' is supported
+ lastErrorMessage = ajax_content.message + '<br />\nAdditionally an unknown status ' + ajax_content.status + ' was detected.';
+ } else if (ajax_content.status == 'failed') {
+ // Something bad went wrong so copy the message
+ lastErrorMessage = ajax_content.message;
+ } else {
+ // All fine
+ isResponseDone = true;
+ }
+
+ // Return status
+ return isResponseDone;
+}
+
+// Saves changes by sending the data to the AJAX backend script
+function saveChanges (prefix) {
+ // Mark all elements as unchanged
+ markAllElementsAsUnchanged();
+
+ // Do we have changed elements
+ 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) {
+ // 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>');
+ }
+
+ // Serialize the whole form
+ var serializedData = $('form').serialize();
+
+ // Hold the ready status
+ $.holdReady(true);
+ saveChangesPending = true;
+
+ /*
+ * 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) {
+ // Get the content
+ var ajax_content = getAjaxContent();
+
+ // Process the returned content
+ if (processAjaxResponseContent(prefix, ajax_content) == true) {
+ // Mark all elements as unchanged
+ markAllElementsAsUnchanged();
+
+ // Reset form
+ resetMailerAjaxForm();
+ } else {
+ // Do we have 'failed_fields' set?
+ if ((ajax_content.failed_fields != undefined) && (ajax_content.message != undefined)) {
+ // Mark all fields as 'failed'
+ markFormFieldsFailed(ajax_content.failed_fields);
+
+ // Display the error message
+ 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>');
+ }
+ }
+
+ // Saving changes may have worked
+ saveChangesPending = false;
+ } else {
+ // Mark all elements as unchanged
+ markAllElementsAsUnchanged();
+
+ // Display error message
+ displayErrorWindow(prefix, getAjaxContent());
+
+ // Saving changes didn't work
+ saveChangesPending = false;
+ }
+
+ // Wait for all has finished
+ saveChangesLocked();
+}
+
+// Waiting for resources being loaded
+function saveChangesLocked () {
+ // Has all been loaded?
+ if (saveChangesPending == false) {
+ // Then release ready()
+ $.holdReady(false);
+ } else {
+ // Recursive call again
+ window.setTimeout('saveChangesLocked()', 10);
+ }
+}
+
+// Saves changed settings and continues with given page (next/previous)
+function doSaveChangesPage (prefix, htmlId, page) {
+ // Save the changes
+ saveChanges(prefix);
+
+ // Close the window
+ //* DEBUG: */ alert('doSaveChangesPage(): prefix=' + prefix + ',htmlId=' + htmlId + ',page=' + page + ' - calling closeWarningWindow()');
+ closeWarningWindow(prefix, true, false);
+
+ // Load requested page
+ doFooterPage(prefix, htmlId, page);
+}
+
+// Saves changed settings and continues with given tab
+function doSaveChangesContinue (prefix, htmlId, tab) {
+ // Save the changes
+ saveChanges(prefix);
+
+ // Close the window
+ //* DEBUG: */ alert('doSaveChangesPage(): prefix=' + prefix + ',htmlId=' + htmlId + ',tab=' + tab + ' - calling closeWarningWindow()');
+ closeWarningWindow(prefix, true, false);
+
+ // Load requested content
+ requestAjaxContent(prefix, htmlId, tab);
+}