CRM-14843 - fixes for upgrade script including INSERT IGNORE usage.
[civicrm-core.git] / js / crm.ajax.js
index 9246d89cc11e1c9c37032931ef7ad130d25cb4fa..8d785e82c03d35eecbf1e2420f40e71788805961 100644 (file)
@@ -3,7 +3,7 @@
  * @see https://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface
  * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms
  */
-(function($, CRM) {
+(function($, CRM, undefined) {
   /**
    * Almost like {crmURL} but on the client side
    * eg: var url = CRM.url('civicrm/contact/view', {reset:1,cid:42});
       }
       $('<div id="'+ settings.target.substring(1) +'"><div class="crm-loading-element">' + ts('Loading') + '...</div></div>').dialog(settings.dialog);
       $(settings.target).on('dialogclose', function() {
-        if (!$(this).data('hasUnsavedChanges')) {
+        if ($(this).attr('data-unsaved-changes') !== 'true') {
           $(this).crmSnippet('destroy').dialog('destroy').remove();
         }
       });
         refreshAction: ['next_new', 'submit_savenext', 'upload_new'],
         cancelButton: '.cancel',
         openInline: 'a.open-inline, a.button, a.action-item',
-        onCancel: function(event) {},
-        onError: function(data) {
-          var $el = $(this);
-          $el.html(data.content).trigger('crmLoad', data).trigger('crmFormLoad', data).trigger('crmFormError', data);
-          if (typeof(data.errors) == 'object') {
-            $.each(data.errors, function(formElement, msg) {
-              $('[name="'+formElement+'"]', $el).crmError(msg);
-            });
-          }
-        }
+        onCancel: function(event) {}
       }
     };
     // Move options that belong to crmForm. Others will be passed through to crmSnippet
 
     var widget = CRM.loadPage(url, settings).off('.crmForm');
 
+    // CRM-14353 - Warn of unsaved changes for all forms except those which have opted out
     function cancelAction() {
-      var dirty = CRM.utils.initialValueChanged(widget),
-        title = widget.dialog('option', 'title');
-      widget.data('hasUnsavedChanges', dirty).dialog('close');
+      var dirty = CRM.utils.initialValueChanged($('form:not([data-warn-changes=false])', widget));
+      widget
+        .attr('data-unsaved-changes', dirty ? 'true' : 'false')
+        .dialog('close');
       if (dirty) {
         var id = widget.attr('id') + '-unsaved-alert',
-          alert = CRM.alert('<p>' + ts('%1 has not been saved.', {1: title}) + '</p><p><a href="#" id="' + id + '">' + ts('Restore') + '</a></p>', ts('Unsaved Changes'), alert, {expires: });
-        $('#' + id).button({icons: {primary: 'ui-icon-arrowreturnthick-1-w'}}).click(function() {
-          widget.dialog('open');
-          alert.close();
-          return false;
+          title = widget.dialog('option', 'title'),
+          alert = CRM.alert('<p>' + ts('%1 has not been saved.', {1: title}) + '</p><p><a href="#" id="' + id + '">' + ts('Restore') + '</a></p>', ts('Unsaved Changes'), 'alert unsaved-dialog', {expires: 60000});
+        $('#' + id).button({icons: {primary: 'ui-icon-arrowreturnthick-1-w'}}).click(function(e) {
+          widget.attr('data-unsaved-changes', 'false').dialog('open');
+          e.preventDefault();
         });
       }
     }
     if (widget.data('uiDialog')) {
-      // This is a bit harsh but we are removing jQuery UI's event handler from the close button and adding our own
-      $('.ui-dialog-titlebar-close').first().off().click(cancelAction);
+      // CRM-14353 - This is a bit harsh but we are removing jQuery UI's event handler from the close button and adding our own
+      widget.parent().find('.ui-dialog-titlebar-close').first().off().click(cancelAction);
     }
 
     widget.on('crmFormLoad.crmForm', function(event, data) {
       var $el = $(this)
-        .data('hasUnsavedChanges', false);
+        .attr('data-unsaved-changes', 'false');
       var settings = $el.crmSnippet('option', 'crmForm');
       settings.cancelButton && $(settings.cancelButton, this).click(function(e) {
         e.preventDefault();
         url: data.url.replace(/reset=1[&]?/, ''),
         dataType: 'json',
         success: function(response) {
-          if (response.status !== 'form_error') {
+          if (response.content === undefined) {
             $el.crmSnippet('option', 'block') && $el.unblock();
             $el.trigger('crmFormSuccess', response);
             // Reset form for e.g. "save and new"
           }
           else {
             response.url = data.url;
-            settings.onError.call($el, response);
+            $el.html(response.content).trigger('crmLoad', response).trigger('crmFormLoad', response);
+            if (response.status === 'form_error') {
+              $el.trigger('crmFormError', response);
+              $.each(response.errors || [], function(formElement, msg) {
+                $('[name="'+formElement+'"]', $el).crmError(msg);
+              });
+            }
           }
         },
         beforeSerialize: function(form, options) {
           return false;
         });
       }
+      // Alow a button to prevent ajax submit
+      $('input[data-no-ajax-submit=true]').click(function() {
+        $(this).closest('form').ajaxFormUnbind();
+      });
       // For convenience, focus the first field
       $('input[type=text], textarea, select', this).filter(':visible').first().not('.dateplugin').focus();
     });
   };
   /**
    * Handler for jQuery click event e.g. $('a').click(CRM.popup)
-   * @returns {boolean}
    */
   CRM.popup = function(e) {
     var $el = $(this).first(),
     e.preventDefault();
   };
   /**
-   * An event callback for CRM.popup or a standalone function to refresh the content around a popup link
+   * An event callback for CRM.popup or a standalone function to refresh the content around a given element
    * @param e event|selector
    */
   CRM.refreshParent = function(e) {
   };
 
   $(function($) {
-    $('body').on('click', 'a.crm-popup', CRM.popup);
+    $('body')
+      .on('click', 'a.crm-popup', CRM.popup)
+      // Close unsaved dialog messages
+      .on('dialogopen', function(e) {
+        $('.alert.unsaved-dialog .ui-notify-cross', '#crm-notification-container').click();
+      })
+      // Destroy old unsaved dialog
+      .on('dialogcreate', function(e) {
+        $('.ui-dialog-content.crm-ajax-container:hidden[data-unsaved-changes=true]').crmSnippet('destroy').dialog('destroy').remove();
+      });
   });
 
 }(jQuery, CRM));