* field for the given field and row.
*/
function handleUserInputField() {
- var row = $(this).closest('tr');
- var field = $('select[id^=mapper][id$="_1"]', row).val();
+ var row = $(this).closest('tr'),
+ entity = $('select[id^=mapper][id$="_0"]', row).val(),
+ field = $('select[id^=mapper][id$="_1"]', row).val();
field = (field === 'world_region') ? 'worldregion_id': field;
var operator = $('select[id^=operator]', row);
var op = operator.val();
buildOperator(operator, operators);
}
+ removeDate(row);
+
// These Ops don't get any input field.
var noFieldOps = ['', 'IS EMPTY', 'IS NOT EMPTY', 'IS NULL', 'IS NOT NULL'];
if ($.inArray(op, noFieldOps) > -1) {
// Hide the fields and return.
- $('.crm-search-value', row).hide().find('input, select').val('');
+ $('.crm-search-value', row).hide().find('input[id^=value]').val('');
return;
}
$('.crm-search-value', row).show();
- if (!CRM.searchBuilder.fieldOptions[field]) {
- removeSelect(row);
+ if (CRM.searchBuilder.fieldOptions[field]) {
+ buildSelect(row, field, op, false);
+ }
+ // Add entityRef widget for all fields except an entity's own id
+ else if (CRM.searchBuilder.fkEntities[field] && field !== (entity.toLowerCase() + '_id')) {
+ buildEntityRef(row, field, op);
}
else {
- buildSelect(row, field, op, false);
+ removeSelect(row);
}
if (CRM.searchBuilder.fieldTypes[field] === 'Date' || CRM.searchBuilder.fieldTypes[field] === 'Timestamp') {
buildDate(row, op, CRM.searchBuilder.fieldTypes[field] === 'Timestamp');
}
- else {
- removeDate(row);
- }
}
/**
operator.val(selected);
}
+ function getSelectType(op) {
+ // Operators that will get a single drop down list of choices.
+ var dropDownSingleOps = ['=', '!='];
+ // Multiple select drop down list.
+ var dropDownMultipleOps = ['IN', 'NOT IN'];
+
+ if ($.inArray(op, dropDownMultipleOps) > -1) {
+ return true;
+ }
+ if ($.inArray(op, dropDownSingleOps) > -1) {
+ return false;
+ }
+ }
+
+ function buildEntityRef(row, field, op) {
+ var selectType = getSelectType(op);
+
+ if (typeof selectType === 'undefined') {
+ removeSelect(row);
+ return;
+ }
+
+ $('input[id^=value]', row)
+ .crmEntityRef({
+ entity: CRM.searchBuilder.fkEntities[field],
+ select: {multiple: selectType, placeholder: ts('Select'), allowClear: true}
+ });
+ }
+
/**
* Add select list if appropriate for this operation
* @param row: jQuery object
* @param skip_fetch: boolean
*/
function buildSelect(row, field, op, skip_fetch) {
- var multiSelect = '';
- // Operators that will get a single drop down list of choices.
- var dropDownSingleOps = ['=', '!='];
- // Multiple select drop down list.
- var dropDownMultipleOps = ['IN', 'NOT IN'];
+ var selectType = getSelectType(op);
- if ($.inArray(op, dropDownMultipleOps) > -1) {
- multiSelect = 'multiple="multiple"';
- }
- else if ($.inArray(op, dropDownSingleOps) < 0) {
- // If this op is neither supported by single or multiple selects, then we should not render a select list.
+ if (typeof selectType === 'undefined') {
removeSelect(row);
return;
}
- $('.crm-search-value select', row).remove();
$('input[id^=value]', row)
- .hide()
- .after('<select class="crm-form-' + multiSelect.substr(0, 5) + 'select required" ' + multiSelect + '><option value="">' + ts('Loading') + '...</option></select>');
+ .addClass('loading')
+ .crmSelect2({data: [], disabled: true, multiple: selectType, placeholder: ts('Select'), allowClear: true});
// Avoid reloading state/county options IF already built, identified by skip_fetch
if (skip_fetch) {
- buildOptions(row, field);
+ buildOptions(row, field, selectType);
}
else {
- fetchOptions(row, field);
+ fetchOptions(row, field, selectType);
}
}
* @param row: jQuery object
* @param field: string
*/
- function fetchOptions(row, field) {
+ function fetchOptions(row, field, multiSelect) {
if (CRM.searchBuilder.fieldOptions[field] === 'yesno') {
CRM.searchBuilder.fieldOptions[field] = [{key: 1, value: ts('Yes')}, {key: 0, value: ts('No')}];
}
var field = settings.field;
if (result.count) {
CRM.searchBuilder.fieldOptions[field] = result.values;
- buildOptions(settings.row, field);
+ buildOptions(settings.row, field, multiSelect);
}
else {
removeSelect(settings.row);
});
}
else {
- buildOptions(row, field);
+ buildOptions(row, field, multiSelect);
}
}
* Populate option list for given row
* @param row: jQuery object
* @param field: string
+ * @param multiSelect: bool
*/
- function buildOptions(row, field) {
- var select = $('.crm-search-value select', row);
- var value = $('input[id^=value]', row).val();
- if (value.length && value.charAt(0) == '(' && value.charAt(value.length - 1) == ')') {
- value = value.slice(1, -1);
- }
- var options = value.split(',');
- if (select.attr('multiple') == 'multiple') {
- select.find('option').remove();
+ function buildOptions(row, field, multiSelect) {
+ var $el = $('input[id^=value]', row).removeClass('loading'),
+ value = $el.val();
+ if (value.length && value.charAt(0) === '(' && value.charAt(value.length - 1) === ')') {
+ $el.val(value.slice(1, -1));
}
- else {
- select.find('option').text(ts('- select -'));
- if (options.length > 1) {
- options = [options[0]];
- }
- }
- $.each(CRM.searchBuilder.fieldOptions[field], function(key, option) {
- var optionKey = option.key;
- if ($.inArray(field, CRM.searchBuilder.searchByLabelFields) >= 0) {
- optionKey = option.value;
- }
- var selected = ($.inArray(''+optionKey, options) > -1) ? 'selected="selected"' : '';
- select.append('<option value="' + optionKey + '"' + selected + '>' + option.value + '</option>');
+ $el.crmSelect2({
+ multiple: multiSelect,
+ placeholder: ts('Select'),
+ allowClear: true,
+ data: _.transform(CRM.searchBuilder.fieldOptions[field], function(options, opt) {
+ options.push({id: opt.key, text: opt.value});
+ }, [])
});
- select.change();
}
/**
* @param row: jQuery object
*/
function removeSelect(row) {
- $('.crm-search-value input', row).not('.crm-hidden-date').show();
- $('.crm-search-value select', row).remove();
+ $('input[id^=value]', row).crmEntityRef('destroy');
}
/**
// Handle field and operator selection
.on('change', 'select[id^=mapper][id$="_1"], select[id^=operator]', handleUserInputField)
// Handle option selection - update hidden value field
- .on('change', '.crm-search-value select', function() {
+ .on('change', '.crm-search-value input[id^=value]', function() {
var value = $(this).val() || '';
- if ($(this).attr('multiple') == 'multiple' && value.length) {
- value = value.join(',');
- }
- $(this).siblings('input').val(value);
if (value !== '') {
- var mapper = $('#' + $(this).siblings('input').attr('id').replace('value_', 'mapper_') + '_1').val();
- var location_type = $('#' + $(this).siblings('input').attr('id').replace('value_', 'mapper_') + '_2').val();
- var section = $(this).siblings('input').attr('id').replace('value_', '').split('_')[0];
+ var mapper = $('#' + $(this).attr('id').replace('value_', 'mapper_') + '_1').val();
+ var location_type = $('#' + $(this).attr('id').replace('value_', 'mapper_') + '_2').val();
+ var section = $(this).attr('id').replace('value_', '').split('_')[0];
if ($.inArray(mapper, ['state_province', 'country']) > -1) {
chainSelect(mapper + '_id', value, location_type, section);
}