Commit | Line | Data |
---|---|---|
6a488035 TO |
1 | // http://civicrm.org/licensing |
2 | (function($, CRM) { | |
057428a0 | 3 | 'use strict'; |
6a488035 TO |
4 | |
5 | /** | |
057428a0 CW |
6 | * Handle user input - field or operator selection. |
7 | * | |
8 | * Decide whether to display select drop down, regular text or date | |
9 | * field for the given field and row. | |
6a488035 | 10 | */ |
057428a0 | 11 | function handleUserInputField() { |
6a488035 | 12 | var row = $(this).closest('tr'); |
057428a0 CW |
13 | var field = $('select[id^=mapper][id$="_1"]', row).val(); |
14 | var op = $('select[id^=operator]', row).val(); | |
15 | ||
16 | // These Ops don't get any input field. | |
17 | var noFieldOps = ['', 'IS EMPTY', 'IS NOT EMPTY', 'IS NULL', 'IS NOT NULL']; | |
18 | ||
19 | if ($.inArray(op, noFieldOps) > -1) { | |
20 | // Hide the fields and return. | |
21 | $('.crm-search-value', row).hide().find('input, select').val(''); | |
22 | return; | |
23 | } | |
24 | $('.crm-search-value', row).show(); | |
25 | ||
6a488035 TO |
26 | if (!CRM.searchBuilder.fieldOptions[field]) { |
27 | removeSelect(row); | |
28 | } | |
6a488035 | 29 | else { |
057428a0 | 30 | buildSelect(row, field, op); |
6a488035 | 31 | } |
6a488035 | 32 | |
057428a0 CW |
33 | if ($.inArray(field, CRM.searchBuilder.dateFields) < 0) { |
34 | removeDate(row); | |
6a488035 | 35 | } |
6a488035 | 36 | else { |
057428a0 | 37 | buildDate(row, op); |
6a488035 TO |
38 | } |
39 | } | |
40 | ||
41 | /** | |
057428a0 | 42 | * Add select list if appropriate for this operation |
6a488035 TO |
43 | * @param row: jQuery object |
44 | * @param field: string | |
45 | */ | |
057428a0 CW |
46 | function buildSelect(row, field, op) { |
47 | var multiSelect = ''; | |
48 | // Operators that will get a single drop down list of choices. | |
49 | var dropDownSingleOps = ['=', '!=']; | |
50 | // Multiple select drop down list. | |
51 | var dropDownMultipleOps = ['IN', 'NOT IN']; | |
52 | ||
53 | if ($.inArray(op, dropDownMultipleOps) > -1) { | |
54 | multiSelect = 'multiple="multiple"'; | |
6a488035 | 55 | } |
057428a0 CW |
56 | else if ($.inArray(op, dropDownSingleOps) < 0) { |
57 | // If this op is neither supported by single or multiple selects, then we should not render a select list. | |
58 | removeSelect(row); | |
59 | return; | |
6a488035 | 60 | } |
057428a0 | 61 | |
6a488035 | 62 | $('.crm-search-value select', row).remove(); |
057428a0 CW |
63 | $('input[id^=value]', row) |
64 | .hide() | |
65 | .after('<select class="form-select required" ' + multiSelect + '><option value="">' + ts('Loading') + '...</option></select>'); | |
66 | ||
6a488035 TO |
67 | fetchOptions(row, field); |
68 | } | |
69 | ||
70 | /** | |
71 | * Retrieve option list for given row | |
72 | * @param row: jQuery object | |
73 | * @param field: string | |
74 | */ | |
75 | function fetchOptions(row, field) { | |
76 | if (CRM.searchBuilder.fieldOptions[field] === 'yesno') { | |
15a1171a | 77 | CRM.searchBuilder.fieldOptions[field] = [{key: 1, value: ts('Yes')}, {key: 0, value: ts('No')}]; |
6a488035 TO |
78 | } |
79 | if (typeof(CRM.searchBuilder.fieldOptions[field]) == 'string') { | |
15a1171a | 80 | CRM.api(CRM.searchBuilder.fieldOptions[field], 'getoptions', {field: field, sequential: 1}, { |
6a488035 TO |
81 | success: function(result, settings) { |
82 | var field = settings.field; | |
83 | if (result.count) { | |
84 | CRM.searchBuilder.fieldOptions[field] = result.values; | |
85 | buildOptions(settings.row, field); | |
86 | } | |
87 | else { | |
88 | removeSelect(settings.row); | |
89 | } | |
90 | }, | |
91 | error: function(result, settings) { | |
92 | removeSelect(settings.row); | |
93 | }, | |
94 | row: row, | |
95 | field: field | |
96 | }); | |
97 | } | |
98 | else { | |
99 | buildOptions(row, field); | |
100 | } | |
101 | } | |
102 | ||
103 | /** | |
104 | * Populate option list for given row | |
105 | * @param row: jQuery object | |
106 | * @param field: string | |
107 | */ | |
108 | function buildOptions(row, field) { | |
109 | var select = $('.crm-search-value select', row); | |
110 | var value = $('input[id^=value]', row).val(); | |
111 | if (value.length && value.charAt(0) == '(' && value.charAt(value.length - 1) == ')') { | |
112 | value = value.slice(1, -1); | |
113 | } | |
114 | var options = value.split(','); | |
057428a0 CW |
115 | if (select.attr('multiple') == 'multiple') { |
116 | select.find('option').remove(); | |
117 | } | |
118 | else { | |
119 | select.find('option').text(ts('- select -')); | |
120 | if (options.length > 1) { | |
121 | options = [options[0]]; | |
122 | } | |
6a488035 | 123 | } |
15a1171a CW |
124 | $.each(CRM.searchBuilder.fieldOptions[field], function(key, option) { |
125 | var selected = ($.inArray(option.key, options) > -1) ? 'selected="selected"' : ''; | |
126 | select.append('<option value="' + option.key + '"' + selected + '>' + option.value + '</option>'); | |
6a488035 TO |
127 | }); |
128 | select.change(); | |
129 | } | |
130 | ||
131 | /** | |
132 | * Remove select options and restore input to a plain textfield | |
133 | * @param row: jQuery object | |
134 | */ | |
135 | function removeSelect(row) { | |
136 | $('.crm-search-value input', row).show(); | |
137 | $('.crm-search-value select', row).remove(); | |
6a488035 TO |
138 | } |
139 | ||
140 | /** | |
057428a0 | 141 | * Add a datepicker if appropriate for this operation |
6a488035 TO |
142 | * @param row: jQuery object |
143 | */ | |
057428a0 | 144 | function buildDate(row, op) { |
6a488035 | 145 | var input = $('.crm-search-value input', row); |
057428a0 CW |
146 | // These are operations that should not get a datepicker |
147 | var datePickerOp = ($.inArray(op, ['IN', 'NOT IN', 'LIKE', 'RLIKE']) < 0); | |
148 | if (!datePickerOp) { | |
149 | removeDate(row); | |
150 | } | |
151 | else if (!input.hasClass('hasDatepicker')) { | |
6a488035 TO |
152 | input.addClass('dateplugin').datepicker({ |
153 | dateFormat: 'yymmdd', | |
154 | changeMonth: true, | |
155 | changeYear: true, | |
156 | yearRange: '-100:+20' | |
157 | }); | |
158 | } | |
159 | } | |
160 | ||
161 | /** | |
162 | * Remove datepicker | |
163 | * @param row: jQuery object | |
164 | */ | |
165 | function removeDate(row) { | |
166 | var input = $('.crm-search-value input', row); | |
167 | if (input.hasClass('hasDatepicker')) { | |
6a488035 TO |
168 | input.removeClass('dateplugin').val('').datepicker('destroy'); |
169 | } | |
170 | } | |
171 | ||
057428a0 CW |
172 | // Initialize display: Hide empty blocks & fields |
173 | var newBlock = CRM.searchBuilder && CRM.searchBuilder.newBlock || 0; | |
174 | $('.crm-search-block', '#Builder').each(function(blockNo) { | |
175 | var block = $(this); | |
176 | var empty = blockNo + 1 > newBlock; | |
177 | var skippedRow = false; | |
178 | $('tr:not(.crm-search-builder-add-row)', block).each(function(rowNo) { | |
179 | var row = $(this); | |
180 | if ($('select:first', row).val() === '') { | |
181 | if (!skippedRow && (rowNo == 0 || blockNo + 1 == newBlock)) { | |
182 | skippedRow = true; | |
6a488035 TO |
183 | } |
184 | else { | |
057428a0 | 185 | row.hide(); |
6a488035 | 186 | } |
057428a0 CW |
187 | } |
188 | else { | |
189 | empty = false; | |
6a488035 TO |
190 | } |
191 | }); | |
057428a0 CW |
192 | if (empty) { |
193 | block.hide(); | |
194 | } | |
195 | }); | |
6a488035 | 196 | |
057428a0 CW |
197 | $('#Builder') |
198 | // Reset and hide row | |
199 | .on('click', '.crm-reset-builder-row', function() { | |
200 | var row = $(this).closest('tr'); | |
201 | $('input, select', row).val('').change(); | |
202 | row.hide(); | |
203 | // Hide entire block if this is the only visible row | |
204 | if (row.siblings(':visible').length < 2) { | |
205 | row.closest('.crm-search-block').hide(); | |
206 | } | |
207 | return false; | |
208 | }) | |
209 | // Add new field - if there's a hidden one, show it | |
210 | // Otherwise allow form to submit and fetch more from the server | |
211 | .on('click', 'input[name^=addMore]', function() { | |
212 | var table = $(this).closest('table'); | |
213 | if ($('tr:hidden', table).length) { | |
214 | $('tr:hidden', table).first().show(); | |
6a488035 | 215 | return false; |
057428a0 CW |
216 | } |
217 | }) | |
218 | // Add new block - if there's a hidden one, show it | |
219 | // Otherwise allow form to submit and fetch more from the server | |
220 | .on('click', '#addBlock', function() { | |
221 | if ($('.crm-search-block:hidden', '#Builder').length) { | |
222 | var block = $('.crm-search-block:hidden', '#Builder').first(); | |
223 | block.show(); | |
224 | $('tr:first-child, tr.crm-search-builder-add-row', block).show(); | |
225 | return false; | |
226 | } | |
227 | }) | |
228 | // Handle field and operator selection | |
229 | .on('change', 'select[id^=mapper][id$="_1"], select[id^=operator]', handleUserInputField) | |
230 | // Handle option selection - update hidden value field | |
231 | .on('change', '.crm-search-value select', function() { | |
232 | var value = $(this).val() || ''; | |
233 | if ($(this).attr('multiple') == 'multiple' && value.length) { | |
234 | value = '(' + value.join(',') + ')'; | |
235 | } | |
236 | $(this).siblings('input').val(value); | |
237 | }) | |
238 | ; | |
239 | ||
240 | $().crmAccordions(); | |
241 | $('select[id^=mapper][id$="_1"]', '#Builder').each(handleUserInputField); | |
6a488035 | 242 | })(cj, CRM); |