X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=js%2FCommon.js;h=945be34461af700fdf5b74a42d651139c580f504;hb=a29e89a5104a7722a48951e16e710dc87f1822d5;hp=26ae4cfaf18c5e2be58409bc7dcadb59ee368c97;hpb=1ec76f38e5f2d5dfba95faa2cc7a5e736fd455ff;p=civicrm-core.git
diff --git a/js/Common.js b/js/Common.js
index 26ae4cfaf1..945be34461 100644
--- a/js/Common.js
+++ b/js/Common.js
@@ -207,32 +207,17 @@ CRM.strings = CRM.strings || {};
* Populate a select list, overwriting the existing options except for the placeholder.
* @param select jquery selector - 1 or more select elements
* @param options array in format returned by api.getoptions
- * @param placeholder string
+ * @param placeholder string|bool - new placeholder or false (default) to keep the old one
+ * @param value string|array - will silently update the element with new value without triggering change
*/
- CRM.utils.setOptions = function(select, options, placeholder) {
+ CRM.utils.setOptions = function(select, options, placeholder, value) {
$(select).each(function() {
var
$elect = $(this),
- val = $elect.val() || [],
- opts = placeholder || placeholder === '' ? '' : '[value!=""]',
- newOptions = '',
- theme = function(options) {
- _.each(options, function(option) {
- if (option.children) {
- newOptions += '';
- } else {
- var selected = ($.inArray('' + option.key, val) > -1) ? 'selected="selected"' : '';
- newOptions += '';
- }
- });
- };
- if (!$.isArray(val)) {
- val = [val];
- }
+ val = value || $elect.val() || [],
+ opts = placeholder || placeholder === '' ? '' : '[value!=""]';
$elect.find('option' + opts).remove();
- theme(options);
+ var newOptions = CRM.utils.renderOptions(options, val);
if (typeof placeholder === 'string') {
if ($elect.is('[multiple]')) {
select.attr('placeholder', placeholder);
@@ -241,8 +226,36 @@ CRM.strings = CRM.strings || {};
}
}
$elect.append(newOptions);
- $elect.trigger('crmOptionsUpdated', $.extend({}, options)).trigger('change');
+ if (!value) {
+ $elect.trigger('crmOptionsUpdated', $.extend({}, options)).trigger('change');
+ }
+ });
+ };
+
+ /**
+ * Render an option list
+ * @param options {array}
+ * @param val {string} default value
+ * @param escapeHtml {bool}
+ * @return string
+ */
+ CRM.utils.renderOptions = function(options, val, escapeHtml) {
+ var rendered = '',
+ esc = escapeHtml === false ? _.identity : _.escape;
+ if (!$.isArray(val)) {
+ val = [val];
+ }
+ _.each(options, function(option) {
+ if (option.children) {
+ rendered += '';
+ } else {
+ var selected = ($.inArray('' + option.key, val) > -1) ? 'selected="selected"' : '';
+ rendered += '';
+ }
});
+ return rendered;
};
function chainSelect() {
@@ -296,6 +309,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;
@@ -327,13 +345,13 @@ CRM.strings = CRM.strings || {};
$el.data('select-params', $.extend({}, $el.data('select-params') || {}, options.select));
$el.data('api-params', $.extend({}, $el.data('api-params') || {}, options.api));
$el.data('create-links', options.create || $el.data('create-links'));
- $el.addClass('crm-form-entityref crm-' + entity + '-ref');
+ $el.addClass('crm-form-entityref crm-' + entity.toLowerCase() + '-ref');
var settings = {
- // Use select2 ajax helper instead of CRM.api because it provides more value
+ // Use select2 ajax helper instead of CRM.api3 because it provides more value
ajax: {
url: CRM.url('civicrm/ajax/rest'),
data: function (input, page_num) {
- var params = $el.data('api-params') || {};
+ var params = getEntityRefApiParams($el);
params.input = input;
params.page_num = page_num;
return {
@@ -373,42 +391,8 @@ CRM.strings = CRM.strings || {};
}
}
};
- if ($el.data('create-links') && entity.toLowerCase() === 'contact') {
- selectParams.formatInputTooShort = function() {
- var txt = $el.data('select-params').formatInputTooShort || $.fn.select2.defaults.formatInputTooShort.call(this);
- if ($el.data('create-links') && CRM.profileCreate && CRM.profileCreate.length) {
- txt += ' ' + ts('or') + '
' + formatSelect2CreateLinks($el);
- }
- return txt;
- };
- selectParams.formatNoMatches = function() {
- var txt = $el.data('select-params').formatNoMatches || $.fn.select2.defaults.formatNoMatches;
- return txt + (CRM.profileCreate ? ('
' + formatSelect2CreateLinks($el)) : '');
- };
- $el.on('select2-open.crmEntity', function() {
- var $el = $(this);
- $('#select2-drop').off('.crmEntity').on('click.crmEntity', 'a.crm-add-entity', function(e) {
- $el.select2('close');
- CRM.loadForm($(this).attr('href'), {
- dialog: {width: 500, height: 'auto'}
- }).on('crmFormSuccess', function(e, data) {
- if (data.status === 'success' && data.id) {
- CRM.status(ts('%1 Created', {1: data.label}));
- if ($el.select2('container').hasClass('select2-container-multi')) {
- var selection = $el.select2('data');
- selection.push(data);
- $el.select2('data', selection, true);
- } else {
- $el.select2('data', data, true);
- }
- }
- });
- return false;
- });
- });
- }
// Create new items inline - works for tags
- else if ($el.data('create-links')) {
+ if ($el.data('create-links') && entity.toLowerCase() === 'tag') {
selectParams.createSearchChoice = function(term, data) {
if (!_.findKey(data, {label: term})) {
return {id: "0", term: term, label: term + ' (' + ts('new tag') + ')'};
@@ -416,9 +400,7 @@ CRM.strings = CRM.strings || {};
};
selectParams.tokenSeparators = [','];
selectParams.createSearchChoicePosition = 'bottom';
- }
- $el.crmSelect2($.extend(settings, $el.data('select-params'), selectParams))
- .on('select2-selecting.crmEntity', function(e) {
+ $el.on('select2-selecting.crmEntity', function(e) {
if (e.val === "0") {
// Create a new term
e.object.label = e.object.term;
@@ -439,9 +421,89 @@ CRM.strings = CRM.strings || {};
});
}
});
+ }
+ else {
+ selectParams.formatInputTooShort = function() {
+ var txt = $el.data('select-params').formatInputTooShort || $.fn.select2.defaults.formatInputTooShort.call(this);
+ txt += renderEntityRefFilters($el) + renderEntityRefCreateLinks($el);
+ return txt;
+ };
+ selectParams.formatNoMatches = function() {
+ var txt = $el.data('select-params').formatNoMatches || $.fn.select2.defaults.formatNoMatches;
+ txt += renderEntityRefFilters($el) + renderEntityRefCreateLinks($el);
+ return txt;
+ };
+ $el.on('select2-open.crmEntity', function() {
+ var $el = $(this);
+ loadEntityRefFilterOptions($el);
+ $('#select2-drop')
+ .off('.crmEntity')
+ .on('click.crmEntity', 'a.crm-add-entity', function(e) {
+ $el.select2('close');
+ CRM.loadForm($(this).attr('href'), {
+ dialog: {width: 500, height: 'auto'}
+ }).on('crmFormSuccess', function(e, data) {
+ if (data.status === 'success' && data.id) {
+ CRM.status(ts('%1 Created', {1: data.label}));
+ if ($el.select2('container').hasClass('select2-container-multi')) {
+ var selection = $el.select2('data');
+ selection.push(data);
+ $el.select2('data', selection, true);
+ } else {
+ $el.select2('data', data, true);
+ }
+ }
+ });
+ return false;
+ })
+ .on('change.crmEntity', 'select.crm-entityref-filter-value', function() {
+ var filter = $el.data('user-filter') || {};
+ filter.value = $(this).val();
+ $(this).toggleClass('active', !!filter.value);
+ $el.data('user-filter', filter);
+ if (filter.value) {
+ // Once a filter has been chosen, rerender create links and refocus the search box
+ $el.select2('close');
+ $el.select2('open');
+ }
+ })
+ .on('change.crmEntity', 'select.crm-entityref-filter-key', function() {
+ var filter = $el.data('user-filter') || {};
+ filter.key = $(this).val();
+ $(this).toggleClass('active', !!filter.key);
+ $el.data('user-filter', filter);
+ loadEntityRefFilterOptions($el);
+ });
+ });
+ }
+ $el.crmSelect2($.extend(settings, $el.data('select-params'), selectParams));
});
};
+ /**
+ * Combine api-params with user-filter
+ * @param $el
+ * @returns {*}
+ */
+ function getEntityRefApiParams($el) {
+ var
+ params = $.extend({params: {}}, $el.data('api-params') || {}),
+ // Prevent original data from being modified - $.extend and _.clone don't cut it, they pass nested objects by reference!
+ combined = _.cloneDeep(params),
+ 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];
+ } else {
+ // Allow json-encoded api filters e.g. {"BETWEEN":[123,456]}
+ combined.params[filter.key] = filter.value.charAt(0) === '{' ? $.parseJSON(filter.value) : filter.value;
+ }
+ }
+ return combined;
+ }
+
CRM.utils.formatSelect2Result = function (row) {
var markup = '