X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=js%2FCommon.js;h=4d2ae26f9ddbcf591b580e23a5a23088d97f32af;hb=40491a7f5b4b52439c453168661177d9a7f61257;hp=9586f9c588cfda0cf10536689141be87058d6ef7;hpb=2cbe2b82e752a963f102442193b3be1932f6546b;p=civicrm-core.git diff --git a/js/Common.js b/js/Common.js index 9586f9c588..4d2ae26f9d 100644 --- a/js/Common.js +++ b/js/Common.js @@ -13,7 +13,13 @@ CRM._ = _; */ function ts(text, params) { "use strict"; - text = CRM.strings[text] || text; + var d = (params && params.domain) ? ('strings::' + params.domain) : null; + if (d && CRM[d] && CRM[d][text]) { + text = CRM[d][text]; + } + else if (CRM['strings'][text]) { + text = CRM['strings'][text]; + } if (typeof(params) === 'object') { for (var i in params) { if (typeof(params[i]) === 'string' || typeof(params[i]) === 'number') { @@ -39,12 +45,14 @@ function ts(text, params) { */ function on_load_init_blocks(showBlocks, hideBlocks, elementType) { if (elementType == null) { - var elementType = 'block'; + elementType = 'block'; } + var myElement, i; + /* This loop is used to display the blocks whose IDs are present within the showBlocks array */ - for (var i = 0; i < showBlocks.length; i++) { - var myElement = document.getElementById(showBlocks[i]); + for (i = 0; i < showBlocks.length; i++) { + myElement = document.getElementById(showBlocks[i]); /* getElementById returns null if element id doesn't exist in the document */ if (myElement != null) { myElement.style.display = elementType; @@ -55,8 +63,8 @@ function on_load_init_blocks(showBlocks, hideBlocks, elementType) { } /* This loop is used to hide the blocks whose IDs are present within the hideBlocks array */ - for (var i = 0; i < hideBlocks.length; i++) { - var myElement = document.getElementById(hideBlocks[i]); + for (i = 0; i < hideBlocks.length; i++) { + myElement = document.getElementById(hideBlocks[i]); /* getElementById returns null if element id doesn't exist in the document */ if (myElement != null) { myElement.style.display = 'none'; @@ -80,13 +88,14 @@ function on_load_init_blocks(showBlocks, hideBlocks, elementType) { * @param invert Boolean - if true, we HIDE target on value match; if false, we SHOW target on value match */ function showHideByValue(trigger_field_id, trigger_value, target_element_id, target_element_type, field_type, invert) { + var target, j; if (field_type == 'select') { var trigger = trigger_value.split("|"); var selectedOptionValue = cj('#' + trigger_field_id).val(); - var target = target_element_id.split("|"); - for (var j = 0; j < target.length; j++) { + target = target_element_id.split("|"); + for (j = 0; j < target.length; j++) { if (invert) { cj('#' + target[j]).show(); } @@ -108,8 +117,8 @@ function showHideByValue(trigger_field_id, trigger_value, target_element_id, tar } else { if (field_type == 'radio') { - var target = target_element_id.split("|"); - for (var j = 0; j < target.length; j++) { + target = target_element_id.split("|"); + for (j = 0; j < target.length; j++) { if (cj('[name="' + trigger_field_id + '"]:first').is(':checked')) { if (invert) { cj('#' + target[j]).hide(); @@ -309,6 +318,11 @@ CRM.strings = CRM.strings || {}; $(this).nextUntil('option[value^=crm_optgroup]').wrapAll(''); $(this).remove(); }); + + // quickform does not support disabled option, so yet another hack to + // add disabled property for option values + $('option[value^=crm_disabled_opt]', this).attr('disabled', 'disabled'); + // Defaults for single-selects if ($el.is('select:not([multiple])')) { settings.minimumResultsForSearch = 10; @@ -488,9 +502,9 @@ CRM.strings = CRM.strings || {}; filter = $.extend({}, $el.data('user-filter') || {}); if (filter.key && filter.value) { // Special case for contact type/sub-type combo - if (filter.key === 'contact_type' && (filter.value.indexOf('.') > 0)) { - combined.params.contact_type = filter.value.split('.')[0]; - combined.params.contact_sub_type = filter.value.split('.')[1]; + if (filter.key === 'contact_type' && (filter.value.indexOf('__') > 0)) { + combined.params.contact_type = filter.value.split('__')[0]; + combined.params.contact_sub_type = filter.value.split('__')[1]; } else { // Allow json-encoded api filters e.g. {"BETWEEN":[123,456]} combined.params[filter.key] = filter.value.charAt(0) === '{' ? $.parseJSON(filter.value) : filter.value; @@ -551,7 +565,7 @@ CRM.strings = CRM.strings || {}; } else if (this.key == 'contact_type' && typeof params.contact_sub_type === 'undefined') { this.options = _.remove(this.options, function(option) { - return option.key.indexOf(params.contact_type + '.') === 0; + return option.key.indexOf(params.contact_type + '__') === 0; }); result.push(this); } @@ -597,7 +611,7 @@ CRM.strings = CRM.strings || {}; CRM.utils.setOptions($valField, filterSpec.options, false, filter.value); } else { $valField.prop('disabled', true); - CRM.api3(filterSpec.entity || $el.data('api-entity'), 'getoptions', {field: filter.key, sequential: 1}) + CRM.api3(filterSpec.entity || $el.data('api-entity'), 'getoptions', {field: filter.key, context: 'search', sequential: 1}) .done(function(result) { var entity = $el.data('api-entity').toLowerCase(), globalFilterSpec = _.find(CRM.config.entityRef.filters[entity], {key: filter.key}) || {}; @@ -613,6 +627,16 @@ CRM.strings = CRM.strings || {}; } } + //CRM-15598 - Override url validator method to allow relative url's (e.g. /index.htm) + $.validator.addMethod("url", function(value, element) { + if (/^\//.test(value)) { + // Relative url: prepend dummy path for validation. + value = 'http://domain.tld' + value; + } + // From jQuery Validation Plugin v1.12.0 + return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }); + /** * Wrapper for jQuery validate initialization function; supplies defaults */ @@ -826,8 +850,9 @@ CRM.strings = CRM.strings || {}; var opts = $.extend({ start: ts('Saving...'), success: ts('Saved'), - error: function() { - CRM.alert(ts('Sorry an error occurred and your information was not saved'), ts('Error')); + error: function(data) { + var msg = $.isPlainObject(data) && data.error_message; + CRM.alert(msg || ts('Sorry an error occurred and your information was not saved'), ts('Error'), 'error'); } }, options || {}); var $msg = $('
' + opts.start + '
') @@ -838,7 +863,9 @@ CRM.strings = CRM.strings || {}; if (endMsg) { $msg.removeClass('status-start').addClass('status-' + status).find('.crm-status-box-msg').html(endMsg); window.setTimeout(function() { - $msg.fadeOut('slow', function() {$msg.remove()}); + $msg.fadeOut('slow', function() { + $msg.remove(); + }); }, 2000); } else { $msg.remove(); @@ -855,6 +882,27 @@ CRM.strings = CRM.strings || {}; }); }; + // Convert an Angular promise to a jQuery promise + CRM.toJqPromise = function(aPromise) { + var jqDeferred = $.Deferred(); + aPromise.then( + function(data) { jqDeferred.resolve(data); }, + function(data) { jqDeferred.reject(data); } + // should we also handle progress events? + ); + return jqDeferred.promise(); + }; + + CRM.toAPromise = function($q, jqPromise) { + var aDeferred = $q.defer(); + jqPromise.then( + function(data) { aDeferred.resolve(data); }, + function(data) { aDeferred.reject(data); } + // should we also handle progress events? + ); + return aDeferred.promise; + }; + /** * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Notification+Reference */ @@ -969,6 +1017,12 @@ CRM.strings = CRM.strings || {}; }; }; + CRM.addStrings = function(domain, strings) { + var bucket = (domain == 'civicrm' ? 'strings' : 'strings::' + domain); + CRM[bucket] = CRM[bucket] || {}; + _.extend(CRM[bucket], strings); + }; + /** * @see https://wiki.civicrm.org/confluence/display/CRMDOC/Notification+Reference */ @@ -993,14 +1047,14 @@ CRM.strings = CRM.strings || {}; title = $label.text(); } } - $(this).addClass('error'); + $(this).addClass('crm-error'); } var msg = CRM.alert(text, title, 'error', $.extend(extra, options)); if ($(this).length) { var ele = $(this); setTimeout(function () { ele.one('change', function () { - msg && msg.close && msg.close(); + if (msg && msg.close) msg.close(); ele.removeClass('error'); label.removeClass('crm-error'); }); @@ -1070,7 +1124,7 @@ CRM.strings = CRM.strings || {}; if (typeof(response.crmMessages) == 'object') { $.each(response.crmMessages, function(n, msg) { CRM.alert(msg.text, msg.title, msg.type, msg.options); - }) + }); } if (response.backtrace) { CRM.console('log', response.backtrace); @@ -1151,7 +1205,9 @@ CRM.strings = CRM.strings || {}; /** * @deprecated */ - $.fn.crmAccordions = function () {}; + $.fn.crmAccordions = function () { + CRM.console('warn', 'Warning: $.crmAccordions was called. This function is deprecated and should not be used.'); + }; /** * Collapse or expand an accordion * @param speed