From 53f2643cb0a1494b7eecfc0be70825cb09437bf9 Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sat, 15 Mar 2014 16:17:52 -0400 Subject: [PATCH] Cleanup and rearrange common js --- CRM/Admin/Form/Preferences/Display.php | 2 +- CRM/Core/Page.php | 2 +- CRM/Core/Resources.php | 19 +- js/Common.js | 302 ------------ js/crm.ajax.js | 440 ++++++++++++++++++ js/crm.optionEdit.js | 23 + js/rest.js | 188 -------- settings/Core.setting.php | 4 +- .../CRM/Admin/Form/Preferences/Display.tpl | 6 +- templates/CRM/Contact/Page/View/Summary.js | 2 +- templates/CRM/common/TabHeader.js | 2 +- 11 files changed, 487 insertions(+), 503 deletions(-) create mode 100644 js/crm.ajax.js create mode 100644 js/crm.optionEdit.js delete mode 100644 js/rest.js diff --git a/CRM/Admin/Form/Preferences/Display.php b/CRM/Admin/Form/Preferences/Display.php index 1c37bd8766..6c1942b079 100644 --- a/CRM/Admin/Form/Preferences/Display.php +++ b/CRM/Admin/Form/Preferences/Display.php @@ -98,7 +98,7 @@ class CRM_Admin_Form_Preferences_Display extends CRM_Admin_Form_Preferences { 'html_type' => NULL, 'weight' => 11, ), - 'ajax_popups_enabled' => array( + 'ajaxPopupsEnabled' => array( 'html_type' => 'checkbox', 'title' => ts('Enable Popup Forms'), 'weight' => 12, diff --git a/CRM/Core/Page.php b/CRM/Core/Page.php index 4973d594fd..3619981d12 100644 --- a/CRM/Core/Page.php +++ b/CRM/Core/Page.php @@ -232,7 +232,7 @@ class CRM_Core_Page { } if ($this->useLivePageJS && - CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'ajax_popups_enabled', NULL, TRUE)) + CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'ajaxPopupsEnabled', NULL, TRUE)) { CRM_Core_Resources::singleton()->addScriptFile('civicrm', 'js/crm.livePage.js'); } diff --git a/CRM/Core/Resources.php b/CRM/Core/Resources.php index 180506de14..45e17deb50 100644 --- a/CRM/Core/Resources.php +++ b/CRM/Core/Resources.php @@ -94,6 +94,11 @@ class CRM_Core_Resources { */ protected $cacheCodeKey = NULL; + /** + * @var bool + */ + public $ajaxPopupsEnabled; + /** * Get or set the single instance of CRM_Core_Resources * @@ -134,6 +139,9 @@ class CRM_Core_Resources { if (!$this->cacheCode) { $this->resetCacheCode(); } + $this->ajaxPopupsEnabled = (bool) CRM_Core_BAO_Setting::getItem( + CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, 'ajaxPopupsEnabled', NULL, TRUE + ); } /** @@ -454,9 +462,7 @@ class CRM_Core_Resources { 'userFramework' => $config->userFramework, 'resourceBase' => $config->resourceBase, 'lcMessages' => $config->lcMessages, - 'ajax_popups_enabled' => (bool) CRM_Core_BAO_Setting::getItem(CRM_Core_BAO_Setting::SYSTEM_PREFERENCES_NAME, - 'ajax_popups_enabled', NULL, TRUE - ) + 'ajaxPopupsEnabled' => $this->ajaxPopupsEnabled, ); $this->addSetting(array('config' => $settings)); @@ -593,8 +599,8 @@ class CRM_Core_Resources { "packages/jquery/plugins/jquery.validate$min.js", "packages/jquery/plugins/jquery.ui.datepicker.validation.pack.js", - "js/rest.js", "js/Common.js", + "js/crm.ajax.js", ); // These scripts are only needed by back-office users @@ -611,6 +617,11 @@ class CRM_Core_Resources { $items[] = "packages/jquery/css/token-input-facebook.css"; } + // Enable administrators to edit option lists in a dialog + if (CRM_Core_Permission::check('administer CiviCRM') && $this->ajaxPopupsEnabled) { + $items[] = "js/crm.optionEdit.js"; + } + // Add localized jQuery UI files if ($config->lcMessages && $config->lcMessages != 'en_US') { // Search for i18n file in order of specificity (try fr-CA, then fr) diff --git a/js/Common.js b/js/Common.js index d0d39419ac..4e3f876a4a 100644 --- a/js/Common.js +++ b/js/Common.js @@ -754,289 +754,6 @@ CRM.validate = CRM.validate || { }); } - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms - */ - $.widget('civi.crmSnippet', { - options: { - url: null, - block: true, - crmForm: null - }, - _originalContent: null, - _originalUrl: null, - isOriginalUrl: function() { - var - args = {}, - same = true, - newUrl = this._formatUrl(this.options.url), - oldUrl = this._formatUrl(this._originalUrl); - // Compare path - if (newUrl.split('?')[0] !== oldUrl.split('?')[0]) { - return false; - } - // Compare arguments - $.each(newUrl.split('?')[1].split('&'), function(k, v) { - var arg = v.split('='); - args[arg[0]] = arg[1]; - }); - $.each(oldUrl.split('?')[1].split('&'), function(k, v) { - var arg = v.split('='); - if (args[arg[0]] !== undefined && arg[1] !== args[arg[0]]) { - same = false; - } - }); - return same; - }, - resetUrl: function() { - this.options.url = this._originalUrl; - }, - _create: function() { - this.element.addClass('crm-ajax-container'); - if (!this.element.is('.crm-container *')) { - this.element.addClass('crm-container'); - } - this._handleOrderLinks(); - // Set default if not supplied - this.options.url = this.options.url || document.location.href; - this._originalUrl = this.options.url; - }, - _onFailure: function(data) { - this.options.block && this.element.unblock(); - this.element.trigger('crmAjaxFail', data); - CRM.alert(ts('Unable to reach the server. Please refresh this page in your browser and try again.'), ts('Network Error'), 'error'); - }, - _formatUrl: function(url) { - // Strip hash - url = url.split('#')[0]; - // Add snippet argument to url - if (url.search(/[&?]snippet=/) < 0) { - url += (url.indexOf('?') < 0 ? '?' : '&') + 'snippet=json'; - } else { - url = url.replace(/snippet=[^&]*/, 'snippet=json'); - } - return url; - }, - // Hack to deal with civicrm legacy sort functionality - _handleOrderLinks: function() { - var that = this; - $('a.crm-weight-arrow', that.element).click(function(e) { - that.options.block && that.element.block(); - $.getJSON(that._formatUrl(this.href)).done(function() { - that.refresh(); - }); - e.stopImmediatePropagation(); - return false; - }); - }, - refresh: function() { - var that = this; - var url = this._formatUrl(this.options.url); - this.options.crmForm && $('form', this.element).ajaxFormUnbind(); - this.options.block && $('.blockOverlay', this.element).length < 1 && this.element.block(); - $.getJSON(url, function(data) { - if (typeof(data) != 'object' || typeof(data.content) != 'string') { - that._onFailure(data); - return; - } - data.url = url; - that.element.trigger('crmBeforeLoad', data); - if (that._originalContent === null) { - that._originalContent = that.element.contents().detach(); - } - that.element.html(data.content); - that._handleOrderLinks(); - that.element.trigger('crmLoad', data); - that.options.crmForm && that.element.trigger('crmFormLoad', data); - }).fail(function() { - that._onFailure(); - }); - }, - _destroy: function() { - this.element.removeClass('crm-ajax-container'); - this.options.crmForm && $('form', this.element).ajaxFormUnbind(); - if (this._originalContent !== null) { - this.element.empty().append(this._originalContent); - } - } - }); - - var dialogCount = 0; - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms - */ - CRM.loadPage = function(url, options) { - var settings = { - target: '#crm-ajax-dialog-' + (dialogCount++), - dialog: false - }; - if (!options || !options.target) { - settings.dialog = { - modal: true, - width: '65%', - height: '75%' - }; - } - options && $.extend(true, settings, options); - settings.url = url; - // Create new dialog - if (settings.dialog) { - // HACK: jQuery UI doesn't support relative height - if (settings.dialog.height && settings.dialog.height.indexOf('%') > 0) { - settings.dialog.height = parseInt($(window).height() * (parseFloat(settings.dialog.height)/100), 10); - } - $('
' + ts('Loading') + '...
').dialog(settings.dialog); - $(settings.target).on('dialogclose', function() { - $(this).crmSnippet('destroy').dialog('destroy').remove(); - }); - } - if (settings.dialog && !settings.dialog.title) { - $(settings.target).on('crmLoad', function(e, data) { - if (e.target === $(settings.target)[0] && data && data.title) { - $(this).dialog('option', 'title', data.title); - } - }); - } - $(settings.target).crmSnippet(settings).crmSnippet('refresh'); - return $(settings.target); - }; - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms - */ - CRM.loadForm = function(url, options) { - var settings = { - crmForm: { - ajaxForm: {}, - autoClose: true, - validate: true, - refreshAction: ['next_new', 'submit_savenext'], - cancelButton: '.cancel.form-submit', - openInline: 'a.open-inline, a.button:not("[href=#], .no-popup")', - 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); - }); - } - } - } - }; - // Move options that belong to crmForm. Others will be passed through to crmSnippet - options && $.each(options, function(key, value) { - if (typeof(settings.crmForm[key]) !== 'undefined') { - settings.crmForm[key] = value; - } - else { - settings[key] = value; - } - }); - - var widget = CRM.loadPage(url, settings).off('.crmForm'); - - widget.on('crmFormLoad.crmForm', function(event, data) { - var $el = $(this); - var settings = $el.crmSnippet('option', 'crmForm'); - settings.cancelButton && $(settings.cancelButton, this).click(function(event) { - var returnVal = settings.onCancel.call($el, event); - if (returnVal !== false) { - $el.trigger('crmFormCancel', event); - if ($el.data('uiDialog') && settings.autoClose) { - $el.dialog('close'); - } - else if (!settings.autoClose) { - $el.crmSnippet('resetUrl').crmSnippet('refresh'); - } - } - return returnVal === false; - }); - if (settings.validate) { - $("form", this).validate(typeof(settings.validate) == 'object' ? settings.validate : CRM.validate.params); - } - $("form", this).ajaxForm($.extend({ - url: data.url.replace(/reset=1[&]?/, ''), - dataType: 'json', - success: function(response) { - if (response.status !== 'form_error') { - $el.crmSnippet('option', 'block') && $el.unblock(); - $el.trigger('crmFormSuccess', response); - // Reset form for e.g. "save and new" - if (response.userContext && settings.refreshAction && $.inArray(response.buttonName, settings.refreshAction) >= 0) { - $el.crmSnippet('option', 'url', response.userContext).crmSnippet('refresh'); - } - else if ($el.data('uiDialog') && settings.autoClose) { - $el.dialog('close'); - } - else if (settings.autoClose === false) { - $el.crmSnippet('resetUrl').crmSnippet('refresh'); - } - } - else { - response.url = data.url; - settings.onError.call($el, response); - } - }, - beforeSerialize: function(form, options) { - if (window.CKEDITOR && window.CKEDITOR.instances) { - $.each(CKEDITOR.instances, function() { - this.updateElement && this.updateElement(); - }); - } - }, - beforeSubmit: function(submission) { - $el.crmSnippet('option', 'block') && $el.block(); - $el.trigger('crmFormSubmit', submission); - } - }, settings.ajaxForm)); - if (settings.openInline) { - settings.autoClose = $el.crmSnippet('isOriginalUrl'); - $(settings.openInline, this).click(function(event) { - $el.crmSnippet('option', 'url', $(this).attr('href')).crmSnippet('refresh'); - return false; - }); - } - // For convenience, focus the first field - $('input[type=text], textarea, select', this).filter(':visible').first().focus(); - }); - return widget; - }; - /** - * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms - */ - CRM.popup = function() { - var $el = $(this).first(), - url = $el.attr('href'), - popup = $el.data('popup-type') === 'page' ? CRM.loadPage : CRM.loadForm, - settings = $el.data('popup-settings') || {}, - triggers = {dialogclose: 'crmPopupClose', crmLoad: 'crmPopupLoad', crmFormSuccess: 'crmPopupFormSuccess'}; - settings.dialog = settings.dialog || {}; - if (!CRM.config.ajax_popups_enabled || !url || url.charAt(0) === '#' || $el.attr('onclick') || $el.hasClass('no-popup')) { - return; - } - // Sized based on css class with hack to make delete dialogs smaller - if ($el.hasClass('small-popup') || url.indexOf('/delete') > 0 || url.indexOf('action=delete') > 0) { - settings.dialog.width = 400; - settings.dialog.height = 300; - } - else if ($el.hasClass('medium-popup')) { - settings.dialog.width = settings.dialog.height = '50%'; - } - else if ($el.hasClass('huge-popup')) { - settings.dialog.height = '95%'; - } - var dialog = popup(url, settings); - // Trigger events from the dialog on the original link element - $el.trigger('crmPopupOpen', [dialog]); - $.each(triggers, function(event, target) { - dialog.on(event, function(e, data) { - $el.trigger(target, [dialog, data]); - }); - }); - return false; - }; - // Preprocess all cj ajax calls to display messages $(document).ajaxSuccess(function(event, xhr, settings) { try { @@ -1060,7 +777,6 @@ CRM.validate = CRM.validate || { $.widget('civi.crmAutocomplete', $.ui.autocomplete, {}); $(function () { - var optionsChanged; // Trigger crmLoad on initial content for consistency. It will also be triggered for ajax-loaded content. $('.crm-container').trigger('crmLoad'); @@ -1092,24 +808,6 @@ CRM.validate = CRM.validate || { } }) - // Edit option lists - .on('click', 'a.crm-option-edit-link', CRM.popup) - .on('crmPopupOpen crmPopupFormSuccess', 'a.crm-option-edit-link', function(e) { - optionsChanged = e.type === 'crmPopupFormSuccess'; - }) - .on('crmPopupClose', 'a.crm-option-edit-link', function() { - if (optionsChanged) { - link.trigger('crmOptionsEdited'); - var $elects = $('select[data-option-edit-path="' + link.data('option-edit-path') + '"]'); - if ($elects.data('api-entity') && $elects.data('api-field')) { - CRM.api3($elects.data('api-entity'), 'getoptions', {sequential: 1, field: $elects.data('api-field')}) - .done(function (data) { - CRM.utils.setOptions($elects, data.values); - }); - } - } - }) - // Handle clear button for form elements .on('click', 'a.crm-clear-link', function() { $(this).css({visibility: 'hidden'}).siblings('.crm-form-radio:checked').prop('checked', false).change(); diff --git a/js/crm.ajax.js b/js/crm.ajax.js new file mode 100644 index 0000000000..a90e4f7d97 --- /dev/null +++ b/js/crm.ajax.js @@ -0,0 +1,440 @@ +// https://civicrm.org/licensing +/** + * @see https://wiki.civicrm.org/confluence/display/CRMDOC/AJAX+Interface + * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Ajax+Pages+and+Forms + */ +(function($, CRM) { + /** + * Almost like {crmURL} but on the client side + * eg: var url = CRM.url('civicrm/contact/view', {reset:1,cid:42}); + * or: $('a.my-link').crmURL(); + */ + var tplURL = '/civicrm/example?placeholder'; + var urlInitted = false; + CRM.url = function (p, params) { + if (p == "init") { + tplURL = params; + urlInitted = true; + return; + } + if (!urlInitted) { + console && console.log && console.log('Warning: CRM.url called before initialization'); + } + params = params || ''; + var frag = p.split ('?'); + var url = tplURL.replace("civicrm/example", frag[0]); + + if (typeof(params) == 'string') { + url = url.replace("placeholder", params); + } + else { + url = url.replace("placeholder", $.param(params)); + } + if (frag[1]) { + url += (url.indexOf('?') === (url.length - 1) ? '' : '&') + frag[1]; + } + // remove trailing "?" + if (url.indexOf('?') === (url.length - 1)) { + url = url.slice(0, (url.length - 1)); + } + return url; + }; + + // Backwards compatible with jQuery fn + $.extend ({'crmURL': + function (p, params) { + console && console.log && console.log('Calling crmURL from jQuery is deprecated. Please use CRM.url() instead.'); + return CRM.url(p, params); + } + }); + + $.fn.crmURL = function () { + return this.each(function() { + if (this.href) { + this.href = CRM.url(this.href); + } + }); + }; + + /** + * AJAX api + */ + CRM.api3 = function(entity, action, params, status) { + if (typeof(entity) === 'string') { + params = { + entity: entity, + action: action.toLowerCase(), + json: JSON.stringify(params || {}) + }; + } else { + params = { + entity: 'api3', + action: 'call', + json: JSON.stringify(entity) + } + } + var ajax = $.ajax({ + url: CRM.url('civicrm/ajax/rest'), + dataType: 'json', + data: params, + type: params.action.indexOf('get') < 0 ? 'POST' : 'GET' + }); + if (status) { + // Default status messages + if (status === true) { + status = {success: params.action === 'delete' ? ts('Removed') : ts('Saved')}; + if (params.action.indexOf('get') === 0) { + status.start = ts('Loading...'); + status.success = null; + } + } + var messages = status === true ? {} : status; + CRM.status(status, ajax); + } + return ajax; + }; + + /** + * @deprecated + * AJAX api + */ + CRM.api = function(entity, action, params, options) { + // Default settings + var settings = { + context: null, + success: function(result, settings) { + return true; + }, + error: function(result, settings) { + $().crmError(result.error_message, ts('Error')); + return false; + }, + callBack: function(result, settings) { + if (result.is_error == 1) { + return settings.error.call(this, result, settings); + } + return settings.success.call(this, result, settings); + }, + ajaxURL: 'civicrm/ajax/rest' + }; + action = action.toLowerCase(); + // Default success handler + switch (action) { + case "update": + case "create": + case "setvalue": + case "replace": + settings.success = function() { + CRM.status(ts('Saved')); + return true; + }; + break; + case "delete": + settings.success = function() { + CRM.status(ts('Removed')); + return true; + }; + } + params = { + entity: entity, + action: action, + json: JSON.stringify(params) + }; + // Pass copy of settings into closure to preserve its value during multiple requests + (function(stg) { + $.ajax({ + url: stg.ajaxURL.indexOf('http') === 0 ? stg.ajaxURL : CRM.url(stg.ajaxURL), + dataType: 'json', + data: params, + type: action.indexOf('get') < 0 ? 'POST' : 'GET', + success: function(result) { + stg.callBack.call(stg.context, result, stg); + } + }); + })($.extend({}, settings, options)); + }; + + /** + * Backwards compatible with jQuery fn + * @deprecated + */ + $.fn.crmAPI = function(entity, action, params, options) { + console && console.log && console.log('Calling crmAPI from jQuery is deprecated. Please use CRM.api() instead.'); + return CRM.api.call(this, entity, action, params, options); + }; + + $.widget('civi.crmSnippet', { + options: { + url: null, + block: true, + crmForm: null + }, + _originalContent: null, + _originalUrl: null, + isOriginalUrl: function() { + var + args = {}, + same = true, + newUrl = this._formatUrl(this.options.url), + oldUrl = this._formatUrl(this._originalUrl); + // Compare path + if (newUrl.split('?')[0] !== oldUrl.split('?')[0]) { + return false; + } + // Compare arguments + $.each(newUrl.split('?')[1].split('&'), function(k, v) { + var arg = v.split('='); + args[arg[0]] = arg[1]; + }); + $.each(oldUrl.split('?')[1].split('&'), function(k, v) { + var arg = v.split('='); + if (args[arg[0]] !== undefined && arg[1] !== args[arg[0]]) { + same = false; + } + }); + return same; + }, + resetUrl: function() { + this.options.url = this._originalUrl; + }, + _create: function() { + this.element.addClass('crm-ajax-container'); + if (!this.element.is('.crm-container *')) { + this.element.addClass('crm-container'); + } + this._handleOrderLinks(); + // Set default if not supplied + this.options.url = this.options.url || document.location.href; + this._originalUrl = this.options.url; + }, + _onFailure: function(data) { + this.options.block && this.element.unblock(); + this.element.trigger('crmAjaxFail', data); + CRM.alert(ts('Unable to reach the server. Please refresh this page in your browser and try again.'), ts('Network Error'), 'error'); + }, + _formatUrl: function(url) { + // Strip hash + url = url.split('#')[0]; + // Add snippet argument to url + if (url.search(/[&?]snippet=/) < 0) { + url += (url.indexOf('?') < 0 ? '?' : '&') + 'snippet=json'; + } else { + url = url.replace(/snippet=[^&]*/, 'snippet=json'); + } + return url; + }, + // Hack to deal with civicrm legacy sort functionality + _handleOrderLinks: function() { + var that = this; + $('a.crm-weight-arrow', that.element).click(function(e) { + that.options.block && that.element.block(); + $.getJSON(that._formatUrl(this.href)).done(function() { + that.refresh(); + }); + e.stopImmediatePropagation(); + return false; + }); + }, + refresh: function() { + var that = this; + var url = this._formatUrl(this.options.url); + this.options.crmForm && $('form', this.element).ajaxFormUnbind(); + this.options.block && $('.blockOverlay', this.element).length < 1 && this.element.block(); + $.getJSON(url, function(data) { + if (typeof(data) != 'object' || typeof(data.content) != 'string') { + that._onFailure(data); + return; + } + data.url = url; + that.element.trigger('crmBeforeLoad', data); + if (that._originalContent === null) { + that._originalContent = that.element.contents().detach(); + } + that.element.html(data.content); + that._handleOrderLinks(); + that.element.trigger('crmLoad', data); + that.options.crmForm && that.element.trigger('crmFormLoad', data); + }).fail(function() { + that._onFailure(); + }); + }, + _destroy: function() { + this.element.removeClass('crm-ajax-container'); + this.options.crmForm && $('form', this.element).ajaxFormUnbind(); + if (this._originalContent !== null) { + this.element.empty().append(this._originalContent); + } + } + }); + + var dialogCount = 0; + CRM.loadPage = function(url, options) { + var settings = { + target: '#crm-ajax-dialog-' + (dialogCount++), + dialog: false + }; + if (!options || !options.target) { + settings.dialog = { + modal: true, + width: '65%', + height: '75%' + }; + } + options && $.extend(true, settings, options); + settings.url = url; + // Create new dialog + if (settings.dialog) { + // HACK: jQuery UI doesn't support relative height + if (settings.dialog.height && settings.dialog.height.indexOf('%') > 0) { + settings.dialog.height = parseInt($(window).height() * (parseFloat(settings.dialog.height)/100), 10); + } + $('
' + ts('Loading') + '...
').dialog(settings.dialog); + $(settings.target).on('dialogclose', function() { + $(this).crmSnippet('destroy').dialog('destroy').remove(); + }); + } + if (settings.dialog && !settings.dialog.title) { + $(settings.target).on('crmLoad', function(e, data) { + if (e.target === $(settings.target)[0] && data && data.title) { + $(this).dialog('option', 'title', data.title); + } + }); + } + $(settings.target).crmSnippet(settings).crmSnippet('refresh'); + return $(settings.target); + }; + CRM.loadForm = function(url, options) { + var settings = { + crmForm: { + ajaxForm: {}, + autoClose: true, + validate: true, + refreshAction: ['next_new', 'submit_savenext'], + cancelButton: '.cancel.form-submit', + openInline: 'a.open-inline, a.button:not("[href=#], .no-popup")', + 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); + }); + } + } + } + }; + // Move options that belong to crmForm. Others will be passed through to crmSnippet + options && $.each(options, function(key, value) { + if (typeof(settings.crmForm[key]) !== 'undefined') { + settings.crmForm[key] = value; + } + else { + settings[key] = value; + } + }); + + var widget = CRM.loadPage(url, settings).off('.crmForm'); + + widget.on('crmFormLoad.crmForm', function(event, data) { + var $el = $(this); + var settings = $el.crmSnippet('option', 'crmForm'); + settings.cancelButton && $(settings.cancelButton, this).click(function(event) { + var returnVal = settings.onCancel.call($el, event); + if (returnVal !== false) { + $el.trigger('crmFormCancel', event); + if ($el.data('uiDialog') && settings.autoClose) { + $el.dialog('close'); + } + else if (!settings.autoClose) { + $el.crmSnippet('resetUrl').crmSnippet('refresh'); + } + } + return returnVal === false; + }); + if (settings.validate) { + $("form", this).validate(typeof(settings.validate) == 'object' ? settings.validate : CRM.validate.params); + } + $("form", this).ajaxForm($.extend({ + url: data.url.replace(/reset=1[&]?/, ''), + dataType: 'json', + success: function(response) { + if (response.status !== 'form_error') { + $el.crmSnippet('option', 'block') && $el.unblock(); + $el.trigger('crmFormSuccess', response); + // Reset form for e.g. "save and new" + if (response.userContext && settings.refreshAction && $.inArray(response.buttonName, settings.refreshAction) >= 0) { + $el.crmSnippet('option', 'url', response.userContext).crmSnippet('refresh'); + } + else if ($el.data('uiDialog') && settings.autoClose) { + $el.dialog('close'); + } + else if (settings.autoClose === false) { + $el.crmSnippet('resetUrl').crmSnippet('refresh'); + } + } + else { + response.url = data.url; + settings.onError.call($el, response); + } + }, + beforeSerialize: function(form, options) { + if (window.CKEDITOR && window.CKEDITOR.instances) { + $.each(CKEDITOR.instances, function() { + this.updateElement && this.updateElement(); + }); + } + }, + beforeSubmit: function(submission) { + $el.crmSnippet('option', 'block') && $el.block(); + $el.trigger('crmFormSubmit', submission); + } + }, settings.ajaxForm)); + if (settings.openInline) { + settings.autoClose = $el.crmSnippet('isOriginalUrl'); + $(settings.openInline, this).click(function(event) { + $el.crmSnippet('option', 'url', $(this).attr('href')).crmSnippet('refresh'); + return false; + }); + } + // For convenience, focus the first field + $('input[type=text], textarea, select', this).filter(':visible').first().focus(); + }); + return widget; + }; + /** + * Handler for jQuery click event e.g. $('a').click(CRM.popup) + * @returns {boolean} + */ + CRM.popup = function() { + var $el = $(this).first(), + url = $el.attr('href'), + popup = $el.data('popup-type') === 'page' ? CRM.loadPage : CRM.loadForm, + settings = $el.data('popup-settings') || {}, + triggers = {dialogclose: 'crmPopupClose', crmLoad: 'crmPopupLoad', crmFormSuccess: 'crmPopupFormSuccess'}; + settings.dialog = settings.dialog || {}; + if (!CRM.config.ajaxPopupsEnabled || !url || url.charAt(0) === '#' || $el.attr('onclick') || $el.hasClass('no-popup')) { + return; + } + // Sized based on css class with hack to make delete dialogs smaller + if ($el.hasClass('small-popup') || url.indexOf('/delete') > 0 || url.indexOf('action=delete') > 0) { + settings.dialog.width = 400; + settings.dialog.height = 300; + } + else if ($el.hasClass('medium-popup')) { + settings.dialog.width = settings.dialog.height = '50%'; + } + else if ($el.hasClass('huge-popup')) { + settings.dialog.height = '95%'; + } + var dialog = popup(url, settings); + // Trigger events from the dialog on the original link element + $el.trigger('crmPopupOpen', [dialog]); + $.each(triggers, function(event, target) { + dialog.on(event, function(e, data) { + $el.trigger(target, [dialog, data]); + }); + }); + return false; + }; +}(jQuery, CRM)); diff --git a/js/crm.optionEdit.js b/js/crm.optionEdit.js new file mode 100644 index 0000000000..7a343e2154 --- /dev/null +++ b/js/crm.optionEdit.js @@ -0,0 +1,23 @@ +// https://civicrm.org/licensing +// Enable administrators to edit option lists in a dialog +jQuery(function($) { + var optionsChanged; + $('body') + // Edit option lists + .on('click', 'a.crm-option-edit-link', CRM.popup) + .on('crmPopupOpen crmPopupFormSuccess', 'a.crm-option-edit-link', function(e) { + optionsChanged = e.type === 'crmPopupFormSuccess'; + }) + .on('crmPopupClose', 'a.crm-option-edit-link', function() { + if (optionsChanged) { + $(this).trigger('crmOptionsEdited'); + var $elects = $('select[data-option-edit-path="' + $(this).data('option-edit-path') + '"]'); + if ($elects.data('api-entity') && $elects.data('api-field')) { + CRM.api3($elects.data('api-entity'), 'getoptions', {sequential: 1, field: $elects.data('api-field')}) + .done(function (data) { + CRM.utils.setOptions($elects, data.values); + }); + } + } + }) +}); diff --git a/js/rest.js b/js/rest.js deleted file mode 100644 index 3e9f726165..0000000000 --- a/js/rest.js +++ /dev/null @@ -1,188 +0,0 @@ -/* - +--------------------------------------------------------------------+ - | CiviCRM version 4.4 | - +--------------------------------------------------------------------+ - | This file is a part of CiviCRM. | - | | - | CiviCRM is free software; you can copy, modify, and distribute it | - | under the terms of the GNU Affero General Public License | - | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | - | | - | CiviCRM 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 Affero General Public License for more details. | - | | - | You should have received a copy of the GNU Affero General Public | - | License and the CiviCRM Licensing Exception along | - | with this program; if not, contact CiviCRM LLC | - | at info[AT]civicrm[DOT]org. If you have questions about the | - | GNU Affero General Public License or the licensing of CiviCRM, | - | see the CiviCRM license FAQ at http://civicrm.org/licensing | - +--------------------------------------------------------------------+ -*/ -/* -* Copyright (C) 2009-2010 Xavier Dutoit -* Licensed to CiviCRM under the Academic Free License version 3.0. -*/ - -var CRM = CRM || {}; - -(function($, CRM) { - /** - * Almost like {crmURL} but on the client side - * eg: var url = CRM.url('civicrm/contact/view', {reset:1,cid:42}); - * or: $('a.my-link').crmURL(); - */ - var tplURL = '/civicrm/example?placeholder'; - var urlInitted = false; - CRM.url = function (p, params) { - if (p == "init") { - tplURL = params; - urlInitted = true; - return; - } - if (!urlInitted) { - console && console.log && console.log('Warning: CRM.url called before initialization'); - } - params = params || ''; - var frag = p.split ('?'); - var url = tplURL.replace("civicrm/example", frag[0]); - - if (typeof(params) == 'string') { - url = url.replace("placeholder", params); - } - else { - url = url.replace("placeholder", $.param(params)); - } - if (frag[1]) { - url += (url.indexOf('?') === (url.length - 1) ? '' : '&') + frag[1]; - } - // remove trailing "?" - if (url.indexOf('?') === (url.length - 1)) { - url = url.slice(0, (url.length - 1)); - } - return url; - }; - - // Backwards compatible with jQuery fn - $.extend ({'crmURL': - function (p, params) { - console && console.log && console.log('Calling crmURL from jQuery is deprecated. Please use CRM.url() instead.'); - return CRM.url(p, params); - } - }); - - $.fn.crmURL = function () { - return this.each(function() { - if (this.href) { - this.href = CRM.url(this.href); - } - }); - }; - - /** - * AJAX api - */ - CRM.api3 = function(entity, action, params, status) { - if (typeof(entity) === 'string') { - params = { - entity: entity, - action: action.toLowerCase(), - json: JSON.stringify(params || {}) - }; - } else { - params = { - entity: 'api3', - action: 'call', - json: JSON.stringify(entity) - } - } - var ajax = $.ajax({ - url: CRM.url('civicrm/ajax/rest'), - dataType: 'json', - data: params, - type: params.action.indexOf('get') < 0 ? 'POST' : 'GET' - }); - if (status) { - // Default status messages - if (status === true) { - status = {success: params.action === 'delete' ? ts('Removed') : ts('Saved')}; - if (params.action.indexOf('get') === 0) { - status.start = ts('Loading...'); - status.success = null; - } - } - var messages = status === true ? {} : status; - CRM.status(status, ajax); - } - return ajax; - }; - - /** - * @deprecated - * AJAX api - */ - CRM.api = function(entity, action, params, options) { - // Default settings - var settings = { - context: null, - success: function(result, settings) { - return true; - }, - error: function(result, settings) { - $().crmError(result.error_message, ts('Error')); - return false; - }, - callBack: function(result, settings) { - if (result.is_error == 1) { - return settings.error.call(this, result, settings); - } - return settings.success.call(this, result, settings); - }, - ajaxURL: 'civicrm/ajax/rest' - }; - action = action.toLowerCase(); - // Default success handler - switch (action) { - case "update": - case "create": - case "setvalue": - case "replace": - settings.success = function() { - CRM.status(ts('Saved')); - return true; - }; - break; - case "delete": - settings.success = function() { - CRM.status(ts('Removed')); - return true; - }; - } - params = { - entity: entity, - action: action, - json: JSON.stringify(params) - }; - // Pass copy of settings into closure to preserve its value during multiple requests - (function(stg) { - $.ajax({ - url: stg.ajaxURL.indexOf('http') === 0 ? stg.ajaxURL : CRM.url(stg.ajaxURL), - dataType: 'json', - data: params, - type: action.indexOf('get') < 0 ? 'POST' : 'GET', - success: function(result) { - stg.callBack.call(stg.context, result, stg); - } - }); - })($.extend({}, settings, options)); - }; - - // Backwards compatible with jQuery fn - $.fn.crmAPI = function(entity, action, params, options) { - console && console.log && console.log('Calling crmAPI from jQuery is deprecated. Please use CRM.api() instead.'); - return CRM.api.call(this, entity, action, params, options); - }; - -})(jQuery, CRM); diff --git a/settings/Core.setting.php b/settings/Core.setting.php index 680560aded..8831c40412 100644 --- a/settings/Core.setting.php +++ b/settings/Core.setting.php @@ -205,10 +205,10 @@ return array ( 'description' => null, 'help_text' => null, ), - 'ajax_popups_enabled' => array( + 'ajaxPopupsEnabled' => array( 'group_name' => 'CiviCRM Preferences', 'group' => 'core', - 'name' => 'ajax_popups_enabled', + 'name' => 'ajaxPopupsEnabled', 'type' => 'Boolean', 'quick_form_type' => 'YesNo', 'default' => 1, diff --git a/templates/CRM/Admin/Form/Preferences/Display.tpl b/templates/CRM/Admin/Form/Preferences/Display.tpl index bb8bdb1586..ec6816dd25 100644 --- a/templates/CRM/Admin/Form/Preferences/Display.tpl +++ b/templates/CRM/Admin/Form/Preferences/Display.tpl @@ -195,9 +195,9 @@ fields).{/ts} {help id="id-editor_id"} - - {$form.ajax_popups_enabled.label} - {$form.ajax_popups_enabled.html} + + {$form.ajaxPopupsEnabled.label} + {$form.ajaxPopupsEnabled.html}   diff --git a/templates/CRM/Contact/Page/View/Summary.js b/templates/CRM/Contact/Page/View/Summary.js index 062d7ef194..1dbc67e53d 100644 --- a/templates/CRM/Contact/Page/View/Summary.js +++ b/templates/CRM/Contact/Page/View/Summary.js @@ -303,7 +303,7 @@ if (url === '#') { CRM.tabHeader.focus($tab); return false; - } else if (CRM.config.ajax_popups_enabled) { + } else if (CRM.config.ajaxPopupsEnabled) { CRM.loadForm(url) .on('crmFormSuccess', function() { CRM.tabHeader.resetTab($tab); diff --git a/templates/CRM/common/TabHeader.js b/templates/CRM/common/TabHeader.js index c28fbb716f..cb19b23a92 100644 --- a/templates/CRM/common/TabHeader.js +++ b/templates/CRM/common/TabHeader.js @@ -29,7 +29,7 @@ cj(function($) { }) }); } - if (ui.tab.hasClass('livePage') && CRM.config.ajax_popups_enabled) { + if (ui.tab.hasClass('livePage') && CRM.config.ajaxPopupsEnabled) { ui.panel .off('click.crmLivePage') .on('click.crmLivePage', 'a.button, a.action-item', CRM.popup) -- 2.25.1