5b1666f7 |
1 | //@todo functions partially moved from tpl but still need an enclosure / cleanup |
2 | // jslinting etc |
3cc60a06 |
3 | CRM.$(function($) { |
5b1666f7 |
4 | cj('.selector-rows').change(function () { |
5 | var options = { |
6 | 'url': CRM.url('civicrm/ajax/batch') |
7 | }; |
8 | |
9 | cj("#Entry").ajaxSubmit(options); |
10 | |
11 | // validate rows |
12 | checkColumns(cj(this)); |
13 | }); |
14 | |
15 | cj('input[name^="soft_credit_contact["]').change(function(){ |
16 | var rowNum = cj(this).attr('id').replace('soft_credit_contact_',''); |
17 | var totalAmount = cj('#field_'+rowNum+'_total_amount').val(); |
18 | //assign total amount as default soft credit amount |
19 | cj('#soft_credit_amount_'+ rowNum).val(totalAmount); |
51fa20cb |
20 | //assign soft credit type default value if any |
21 | cj('#field_'+rowNum+'_soft_credit_type').val(cj('#sct_default_id').val()); |
5b1666f7 |
22 | }); |
23 | |
24 | // validate rows |
25 | validateRow(); |
26 | |
27 | //calculate the actual total for the batch |
28 | calculateActualTotal(); |
29 | |
30 | cj('input[id*="_total_amount"]').bind('keyup change', function () { |
31 | calculateActualTotal(); |
32 | }); |
33 | |
34 | if (CRM.batch.type_id == 1) { |
35 | // hide all dates if send receipt is checked |
36 | hideSendReceipt(); |
37 | |
38 | // hide the receipt date if send receipt is checked |
39 | cj('input[id*="][send_receipt]"]').change(function () { |
40 | showHideReceipt(cj(this)); |
41 | }); |
42 | |
43 | } |
44 | else{ |
45 | cj('select[id^="member_option_"]').each(function () { |
46 | if (cj(this).val() == 1) { |
6f9cd76f |
47 | cj(this).prop('disabled', true); |
5b1666f7 |
48 | } |
49 | }); |
50 | |
51 | // set payment info accord to membership type |
52 | cj('select[id*="_membership_type_0"]').change(function () { |
53 | setPaymentBlock(cj(this), null); |
54 | }); |
55 | |
56 | cj('select[id*="_membership_type_1"]').change(function () { |
57 | setPaymentBlock(cj(this), cj(this).val()); |
58 | }); |
59 | |
60 | } |
61 | |
62 | // line breaks between radio buttons and checkboxes |
63 | cj('input.form-radio').next().after('<br />'); |
64 | cj('input.form-checkbox').next().after('<br />'); |
65 | |
66 | //set the focus on first element |
67 | cj('#primary_contact_1').focus(); |
68 | |
69 | }); |
70 | |
71 | |
72 | function updateContactInfo(blockNo, prefix) { |
73 | var contactHiddenElement = 'input[name="' + prefix + 'contact_select_id[' + blockNo + ']"]'; |
74 | var contactId = cj(contactHiddenElement).val(); |
75 | |
76 | var profileFields = CRM.contact.fieldmap; |
77 | |
78 | CRM.api('Contact', 'get', { |
79 | 'sequential': '1', |
80 | 'contact_id': contactId, |
81 | 'return': CRM.contact.return }, |
82 | { success: function (data) { |
83 | cj.each(data.values[0], function (key, value) { |
84 | // set the values |
85 | var actualFldName = profileFields[key]; |
86 | if (key == 'country' || key == 'state_province') { |
87 | idFldName = key + '_id'; |
88 | value = data.values[0][idFldName]; |
89 | } |
90 | setFieldValue(actualFldName, value, blockNo) |
91 | }); |
92 | |
93 | // for membership batch entry based on contact we need to enable / disable |
94 | // add membership select |
95 | if(CRM.batch.type_id == 2) { |
96 | CRM.api('Membership', 'get', { |
97 | 'sequential': '1', |
6f9cd76f |
98 | 'contact_id': contactId |
5b1666f7 |
99 | }, |
100 | { success: function (data) { |
101 | if (data.count > 0) { |
102 | //get the information on membership type |
103 | var membershipTypeId = data.values[0].membership_type_id; |
104 | var membershipJoinDate = data.values[0].join_date; |
105 | CRM.api('MembershipType', 'get', { |
106 | 'sequential': '1', |
107 | 'id': membershipTypeId |
108 | }, |
109 | { success: function (data) { |
110 | var memTypeContactId = data.values[0].member_of_contact_id; |
6f9cd76f |
111 | cj('select[id="member_option_' + blockNo + '"]').prop('disabled', false).val(2); |
5b1666f7 |
112 | cj('select[id="field_' + blockNo + '_membership_type_0"]').val(memTypeContactId).change(); |
113 | cj('select[id="field_' + blockNo + '_membership_type_1"]').val(membershipTypeId).change(); |
114 | setDateFieldValue('join_date', membershipJoinDate, blockNo) |
115 | } |
116 | }); |
117 | } |
118 | } |
119 | }); |
120 | } |
121 | } |
122 | }); |
123 | } |
124 | |
1283a565 |
125 | function setPaymentBlock(form, memType) { |
126 | var rowID = form.closest('div.crm-grid-row').attr('entity_id'); |
127 | var dataUrl = CRM.url('civicrm/ajax/memType'); |
128 | |
129 | if (!memType) { |
130 | memType = cj('select[id="field_' + rowID + '_membership_type_1"]').val(); |
131 | } |
132 | |
133 | cj.post(dataUrl, {mtype: memType}, function (data) { |
134 | cj('#field_' + rowID + '_financial_type').val(data.financial_type_id); |
135 | cj('#field_' + rowID + '_total_amount').val(data.total_amount).change(); |
136 | }, 'json'); |
137 | } |
138 | |
139 | function hideSendReceipt() { |
140 | cj('input[id*="][send_receipt]"]').each(function () { |
141 | showHideReceipt(cj(this)); |
142 | }); |
143 | } |
144 | |
145 | function showHideReceipt(elem) { |
146 | var rowID = elem.closest('div.crm-grid-row').attr('entity_id'); |
147 | if (elem.prop('checked')) { |
148 | cj('.crm-batch-receipt_date-' + rowID).hide(); |
149 | } |
150 | else { |
151 | cj('.crm-batch-receipt_date-' + rowID).show(); |
152 | } |
153 | } |
154 | |
155 | function validateRow() { |
156 | cj('.selector-rows').each(function () { |
157 | checkColumns(cj(this)); |
158 | }); |
159 | } |
160 | |
161 | function checkColumns(parentRow) { |
162 | // show valid row icon if all required data is field |
163 | var validRow = 0; |
164 | var inValidRow = 0; |
165 | var errorExists = false; |
166 | var rowID = parentRow.closest('div.crm-grid-row').attr('entity_id'); |
167 | |
168 | parentRow.find('div .required').each(function () { |
169 | //special case to handle contact autocomplete select |
170 | var fieldId = cj(this).attr('id'); |
171 | if (fieldId.substring(0, 16) == 'primary_contact_') { |
172 | // if display value is set then make sure we also check if contact id is set |
173 | if (!cj(this).val()) { |
174 | inValidRow++; |
175 | } |
176 | else { |
177 | if (cj(this).val() && !cj('input[name="primary_contact_select_id[' + rowID + ']"]').val()) { |
178 | inValidRow++; |
179 | errorExists = true; |
180 | } |
181 | } |
182 | } |
183 | else { |
184 | if (!cj(this).val()) { |
185 | inValidRow++; |
186 | } |
187 | else { |
188 | if (cj(this).hasClass('error') && !cj(this).hasClass('valid')) { |
189 | errorExists = true; |
190 | } |
191 | else { |
192 | validRow++; |
193 | } |
194 | } |
195 | } |
196 | }); |
197 | |
198 | // this means user has entered some data |
199 | if (errorExists) { |
200 | parentRow.find("div:first span").prop('class', 'batch-invalid'); |
201 | } |
202 | else { |
203 | if (inValidRow == 0 && validRow > 0) { |
204 | parentRow.find("div:first span").prop('class', 'batch-valid'); |
205 | } |
206 | else { |
207 | parentRow.find("div:first span").prop('class', 'batch-edit'); |
208 | } |
209 | } |
210 | } |
211 | |
212 | function calculateActualTotal() { |
213 | var total = 0; |
214 | cj('input[id*="_total_amount"]').each(function () { |
215 | if (cj(this).val()) { |
216 | total += parseFloat(cj(this).val()); |
217 | } |
218 | }); |
219 | |
220 | cj('.batch-actual-total').html(formatMoney(total)); |
221 | } |
222 | |
223 | //money formatting/localization |
224 | function formatMoney(amount) { |
225 | var c = 2; |
226 | var t = CRM.setting.monetaryThousandSeparator; |
227 | var d = CRM.setting.monetaryDecimalPoint; |
228 | |
229 | var n = amount, |
230 | c = isNaN(c = Math.abs(c)) ? 2 : c, |
231 | d = d == undefined ? "," : d, |
232 | t = t == undefined ? "." : t, s = n < 0 ? "-" : "", |
233 | i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", |
234 | j = (j = i.length) > 3 ? j % 3 : 0; |
235 | |
236 | return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); |
237 | } |
238 | |
239 | /** |
240 | * This function is use to setdefault elements via ajax |
241 | * |
242 | * @param fname string field name |
243 | * @return void |
244 | */ |
245 | function setFieldValue(fname, fieldValue, blockNo) { |
246 | var elementId = cj('[name="field[' + blockNo + '][' + fname + ']"]'); |
247 | |
248 | if (elementId.length == 0) { |
249 | elementId = cj('input[type=checkbox][name^="field[' + blockNo + '][' + fname + ']"][type!=hidden]'); |
250 | } |
251 | |
252 | // if element not found than return |
253 | if (elementId.length == 0) { |
254 | return; |
255 | } |
256 | |
257 | //check if it is date element |
258 | var isDateElement = elementId.attr('format'); |
259 | |
260 | // check if it is wysiwyg element |
261 | var editor = elementId.attr('editor'); |
262 | |
263 | //get the element type |
264 | var elementType = elementId.attr('type'); |
265 | |
266 | // set the value for all the elements, elements needs to be handled are |
267 | // select, checkbox, radio, date fields, text, textarea, multi-select |
268 | // wysiwyg editor, advanced multi-select ( to do ) |
269 | if (elementType == 'radio') { |
270 | if (fieldValue) { |
271 | elementId.filter("[value=" + fieldValue + "]").prop("checked", true); |
272 | } |
273 | else { |
274 | elementId.removeProp('checked'); |
275 | } |
276 | } |
277 | else { |
278 | if (elementType == 'checkbox') { |
279 | // handle checkbox |
280 | elementId.removeProp('checked'); |
281 | if (fieldValue) { |
282 | cj.each(fieldValue, function (key, value) { |
283 | cj('input[name="field[' + blockNo + '][' + fname + '][' + value + ']"]').prop('checked', true); |
284 | }); |
285 | } |
286 | } |
287 | else { |
288 | if (editor) { |
289 | switch (editor) { |
290 | case 'ckeditor': |
291 | var elemtId = elementId.attr('id'); |
292 | oEditor = CKEDITOR.instances[elemtId]; |
293 | oEditor.setData(htmlContent); |
294 | break; |
295 | case 'tinymce': |
296 | var elemtId = element.attr('id'); |
297 | tinyMCE.get(elemtId).setContent(htmlContent); |
298 | break; |
299 | case 'joomlaeditor': |
300 | // TO DO |
301 | case 'drupalwysiwyg': |
302 | // TO DO |
303 | default: |
304 | elementId.val(fieldValue); |
305 | } |
306 | } |
307 | else { |
308 | elementId.val(fieldValue); |
309 | } |
310 | } |
311 | } |
312 | |
313 | // since we use different display field for date we also need to set it. |
314 | // also check for date time field and set the value correctly |
315 | if (isDateElement && fieldValue) { |
316 | setDateFieldValue(fname, fieldValue, blockNo) |
317 | } |
318 | } |
319 | |
320 | function setDateFieldValue(fname, fieldValue, blockNo) { |
321 | var dateValues = fieldValue.split(' '); |
322 | |
323 | var actualDateElement = cj('#field_' + blockNo + '_' + fname); |
324 | var date_format = actualDateElement.attr('format'); |
325 | var altDateFormat = 'yy-mm-dd'; |
326 | |
327 | var actualDateValue = cj.datepicker.parseDate(altDateFormat, dateValues[0]); |
328 | |
329 | // format date according to display field |
330 | var hiddenDateValue = cj.datepicker.formatDate('mm/dd/yy', actualDateValue); |
331 | |
332 | actualDateElement.val(hiddenDateValue); |
333 | |
334 | var displayDateValue = actualDateElement.val(); |
335 | if (date_format != 'mm/dd/yy') { |
336 | displayDateValue = cj.datepicker.formatDate(date_format, actualDateValue); |
337 | } |
338 | |
339 | cj('#field_' + blockNo + '_' + fname + '_display').val(displayDateValue); |
340 | |
341 | // need to fix time formatting |
342 | if (dateValues[1]) { |
343 | cj('#field_' + blockNo + '_' + fname + '_time').val(dateValues[1].substr(0, 5)); |
344 | } |
345 | } |