1 // http://civicrm.org/licensing
3 // @var: default select operator options
4 var operators
, operatorCount
;
7 * Handle Field Selection
9 function handleFieldSelection() {
10 var field
= $(this).val();
11 var row
= $(this).closest('tr');
12 if (!CRM
.searchBuilder
.fieldOptions
[field
]) {
15 if ($.inArray(field
, CRM
.searchBuilder
.dateFields
) < 0) {
17 if (CRM
.searchBuilder
.fieldOptions
[field
]) {
18 buildSelect(row
, field
);
27 * Handle Search Operator Selection
29 function handleOperatorSelection() {
30 var noValue
= ['', 'IS EMPTY', 'IS NOT EMPTY', 'IS NULL', 'IS NOT NULL'];
31 var row
= $(this).closest('tr');
32 if ($.inArray($(this).val(), noValue
) < 0) {
33 $('.crm-search-value', row
).show();
34 // Change between multiselect and select when using "IN" operator
35 var select
= $('.crm-search-value select', row
);
37 var value
= select
.val() || '';
38 var multi
= ($(this).val() == 'IN' || $(this).val() == 'NOT IN');
39 select
.attr('multiple', multi
);
41 $('option[value=""]', select
).remove();
43 else if ($('option[value=""]', select
).length
< 1) {
44 $(select
).prepend('<option value="">' + ts('- select -') + '</option>');
46 select
.val(value
).change();
49 // Hide value field if the operator doesn't take a value
51 $('.crm-search-value', row
).hide().find('input, select').val('');
56 * Give user a list of options to choose from
57 * @param row: jQuery object
58 * @param field: string
60 function buildSelect(row
, field
) {
61 // Remove operators that can't be used with a select
62 removeOperators(row
, ['LIKE', 'RLIKE']);
63 var op
= $('select[id^=operator]', row
);
64 if (op
.val() == 'IN' || op
.val() == 'NOT IN') {
65 var multiSelect
= 'multiple="multiple">';
68 var multiSelect
= '><option value="">' + ts('- select -') + '</option>';
70 $('.crm-search-value select', row
).remove();
71 $('input[id^=value]', row
).hide().after('<select class="form-select required" ' + multiSelect
+ '</select>');
72 fetchOptions(row
, field
);
76 * Retrieve option list for given row
77 * @param row: jQuery object
78 * @param field: string
80 function fetchOptions(row
, field
) {
81 if (CRM
.searchBuilder
.fieldOptions
[field
] === 'yesno') {
82 CRM
.searchBuilder
.fieldOptions
[field
] = {1: ts('Yes'), 0: ts('No')};
84 if (typeof(CRM
.searchBuilder
.fieldOptions
[field
]) == 'string') {
85 CRM
.api(CRM
.searchBuilder
.fieldOptions
[field
], 'getoptions', {field
: field
}, {
86 success: function(result
, settings
) {
87 var field
= settings
.field
;
89 CRM
.searchBuilder
.fieldOptions
[field
] = result
.values
;
90 buildOptions(settings
.row
, field
);
93 removeSelect(settings
.row
);
96 error: function(result
, settings
) {
97 removeSelect(settings
.row
);
104 buildOptions(row
, field
);
109 * Populate option list for given row
110 * @param row: jQuery object
111 * @param field: string
113 function buildOptions(row
, field
) {
114 var select
= $('.crm-search-value select', row
);
115 var value
= $('input[id^=value]', row
).val();
116 if (value
.length
&& value
.charAt(0) == '(' && value
.charAt(value
.length
- 1) == ')') {
117 value
= value
.slice(1, -1);
119 var options
= value
.split(',');
120 var op
= $('select[id^=operator]', row
);
121 if (op
.val() != 'IN' && op
.val() != 'NOT IN' && options
.length
> 1) {
122 options
= [options
[0]];
124 $.each(CRM
.searchBuilder
.fieldOptions
[field
], function(value
, label
) {
125 var selected
= ($.inArray(value
, options
) > -1) ? 'selected="selected"' : '';
126 select
.append('<option value="' + value
+ '"' + selected
+ '>' + label
+ '</option>');
132 * Remove select options and restore input to a plain textfield
133 * @param row: jQuery object
135 function removeSelect(row
) {
136 $('.crm-search-value input', row
).show();
137 $('.crm-search-value select', row
).remove();
138 restoreOperators(row
);
143 * @param row: jQuery object
145 function buildDate(row
) {
146 var input
= $('.crm-search-value input', row
);
147 if (!input
.hasClass('hasDatepicker')) {
148 // Remove operators that can't be used with a date
149 removeOperators(row
, ['IN', 'NOT IN', 'LIKE', 'RLIKE', 'IS EMPTY', 'IS NOT EMPTY']);
150 input
.addClass('dateplugin').datepicker({
151 dateFormat
: 'yymmdd',
154 yearRange
: '-100:+20'
161 * @param row: jQuery object
163 function removeDate(row
) {
164 var input
= $('.crm-search-value input', row
);
165 if (input
.hasClass('hasDatepicker')) {
166 restoreOperators(row
);
167 input
.removeClass('dateplugin').val('').datepicker('destroy');
172 * Remove operators from a row
173 * @param row: jQuery object
174 * @param illegal: array
176 function removeOperators(row
, illegal
) {
177 var value
= $('select[id^=operator]').val();
178 $('select[id^=operator] option', row
).each(function() {
179 if ($.inArray($(this).attr('value'), illegal
) > -1) {
183 if (value
!== $('select[id^=operator]').val()) {
184 $('select[id^=operator]').change();
189 * Restore operators to the default
190 * @param row: jQuery object
192 function restoreOperators(row
) {
193 var op
= $('select[id^=operator]', row
);
194 if ($('option', op
).length
!= operatorCount
) {
195 var value
= op
.val();
196 op
.html(operators
).val(value
).change();
200 $('document').ready(function() {
201 operators
= $('#operator_1_0').html();
202 operatorCount
= $('#operator_1_0 option').length
;
204 // Hide empty blocks & fields
205 var newBlock
= CRM
.searchBuilder
&& CRM
.searchBuilder
.newBlock
|| 0;
206 $('#Builder .crm-search-block').each(function(blockNo
) {
208 var empty
= blockNo
+ 1 > newBlock
;
209 var skippedRow
= false;
210 $('tr:not(.crm-search-builder-add-row)', block
).each(function(rowNo
) {
212 if ($('select:first', row
).val() === '') {
213 if (!skippedRow
&& (rowNo
== 0 || blockNo
+ 1 == newBlock
)) {
230 // Reset and hide row
231 .on('click', '.crm-reset-builder-row', function() {
232 var row
= $(this).closest('tr');
233 $('input, select', row
).val('').change();
235 // Hide entire block if this is the only visible row
236 if (row
.siblings(':visible').length
< 2) {
237 row
.closest('.crm-search-block').hide();
241 // Add new field - if there's a hidden one, show it
242 // Otherwise we submit form to fetch more from the server
243 .on('click', 'input[name^=addMore]', function() {
244 var table
= $(this).closest('table');
245 if ($('tr:hidden', table
).length
) {
246 $('tr:hidden', table
).first().show();
250 // Add new block - if there's a hidden one, show it
251 // Otherwise we submit form to fetch more from the server
252 .on('click', '#addBlock', function() {
253 if ($('.crm-search-block:hidden', '#Builder').length
) {
254 var block
= $('.crm-search-block:hidden', '#Builder').first();
256 $('tr:first-child, tr.crm-search-builder-add-row', block
).show();
260 // Handle field selection
261 .on('change', 'select[id^=mapper][id$="_1"]', handleFieldSelection
)
262 // Handle operator selection
263 .on('change', 'select[id^=operator]', handleOperatorSelection
)
264 // Handle option selection - update hidden value field
265 .on('change', '.crm-search-value select', function() {
266 var value
= $(this).val() || '';
267 if ($(this).attr('multiple') == 'multiple' && value
.length
) {
268 value
= '(' + value
.join(',') + ')';
270 $(this).siblings('input').val(value
);
273 $('select[id^=operator]', '#Builder').each(handleOperatorSelection
);
275 $('select[id^=mapper][id$="_1"] option[selected=selected]:not([value=""])', '#Builder').parent().each(handleFieldSelection
);