CRM-13078, help text fix
[civicrm-core.git] / templates / CRM / Batch / Form / Entry.tpl
CommitLineData
6a488035
TO
1{*
2 +--------------------------------------------------------------------+
3 | CiviCRM version 4.3 |
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC (c) 2004-2013 |
6 +--------------------------------------------------------------------+
7 | This file is a part of CiviCRM. |
8 | |
9 | CiviCRM is free software; you can copy, modify, and distribute it |
10 | under the terms of the GNU Affero General Public License |
11 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
12 | |
13 | CiviCRM is distributed in the hope that it will be useful, but |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
16 | See the GNU Affero General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Affero General Public |
19 | License and the CiviCRM Licensing Exception along |
20 | with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25*}
26<div class="batch-entry form-item">
27<div id="help">
b4ae0bee 28 {ts}Click Validate & Process below when you've entered all items for the batch. You can also Save & Continue Later at any time. Go to Administer > Customize Data and Screens > Profiles > Reserved Profiles > to add, remove or change the order of columns.{/ts}
6a488035
TO
29</div>
30{if $batchAmountMismatch}
31 <div class="status message status-warning">
32 <div class="icon alert-icon"></div> {ts}Total for amounts entered below does not match the expected batch total.{/ts}
33 </div>
34 <div class="crm-button crm-button_qf_Entry_upload_force-save">
35 {$form._qf_Entry_upload_force.html}
36 </div>
37 <div class="clear"></div>
38{/if}
39<table class="form-layout-compressed batch-totals">
40 <tr><td class="label">{ts}Total amount expected{/ts}</td><td class="right"><span class="batch-expected-total">{$batchTotal|crmMoney}</span></td></tr>
41 <tr><td class="label">{ts}Total amount entered{/ts}</td><td class="right">{$config->defaultCurrencySymbol} <span class="batch-actual-total"></span></td></tr>
42</table>
43
44<div class="crm-copy-fields crm-grid-table" id="crm-batch-entry-table">
45 <div class="crm-grid-header">
46 <div class="crm-grid-cell">&nbsp;</div>
47 <div class="crm-grid-cell">{ts}Contact{/ts}</div>
48 {if $batchType eq 2 }
49 <div class="crm-grid-cell">&nbsp;</div>
50 {/if}
51 {foreach from=$fields item=field key=fieldName}
52 <div class="crm-grid-cell"><img src="{$config->resourceBase}i/copy.png" alt="{ts 1=$field.title}Click to copy %1 from row one to all rows.{/ts}" fname="{$field.name}" class="action-icon" title="{ts}Click here to copy the value in row one to ALL rows.{/ts}" />{$field.title}</div>
53 {/foreach}
54 </div>
55 {section name='i' start=1 loop=$rowCount}
56 {assign var='rowNumber' value=$smarty.section.i.index}
57 <div class="{cycle values="odd-row,even-row"} selector-rows crm-grid-row" entity_id="{$rowNumber}">
58 <div class="compressed crm-grid-cell"><span class="batch-edit"></span></div>
59 {* contact select/create option*}
60 <div class="compressed crm-grid-cell">
61 {include file="CRM/Contact/Form/NewContact.tpl" blockNo = $rowNumber noLabel=true prefix="primary_" newContactCallback="updateContactInfo($rowNumber, 'primary_')"}
62 </div>
63
64 {if $batchType eq 2 }
65 {$form.member_option.$rowNumber.html}
66 {/if}
67
68 {foreach from=$fields item=field key=fieldName}
69 {assign var=n value=$field.name}
70 {if ( $fields.$n.data_type eq 'Date') or ( in_array( $n, array( 'thankyou_date', 'cancel_date', 'receipt_date', 'receive_date', 'join_date', 'membership_start_date', 'membership_end_date' ) ) ) }
71 <div class="compressed crm-grid-cell"><span class="crm-batch-{$n}-{$rowNumber}">{include file="CRM/common/jcalendar.tpl" elementName=$n elementIndex=$rowNumber batchUpdate=1}</span></div>
72 {elseif $n eq 'soft_credit'}
73 <div class="compressed crm-grid-cell">{include file="CRM/Contact/Form/NewContact.tpl" blockNo = $rowNumber noLabel=true prefix="soft_credit_"}</div>
74 {elseif in_array( $fields.$n.html_type, array('Radio', 'CheckBox'))}
75 <div class="compressed crm-grid-cell">&nbsp;{$form.field.$rowNumber.$n.html}</div>
76 {else}
77 <div class="compressed crm-grid-cell">{$form.field.$rowNumber.$n.html}</div>
78 {/if}
79 {/foreach}
80 </div>
81 {/section}
82</div>
83<div class="crm-submit-buttons">{if $fields}{$form._qf_Batch_refresh.html}{/if} &nbsp; {$form.buttons.html}</div>
84</div>
85{literal}
86<script type="text/javascript">
87 cj(function(){
88 cj('.selector-rows').change(function(){
89 var options = {
90 'url' : {/literal}"{crmURL p='civicrm/ajax/batch' h=0}"{literal}
91 };
92
93 cj("#Entry").ajaxSubmit(options);
94
95 // validate rows
96 checkColumns( cj(this) );
97 });
98
99 // validate rows
100 validateRow( );
101
102 //calculate the actual total for the batch
103 calculateActualTotal();
104
105 cj('input[id*="_total_amount"]').bind('keyup change', function(){
106 calculateActualTotal();
107 });
108
109 {/literal}{if $batchType eq 1 }{literal}
110 // hide all dates if send receipt is checked
111 hideSendReceipt();
112
113 // hide the receipt date if send receipt is checked
114 cj( 'input[id*="][send_receipt]"]').change( function() {
115 showHideReceipt( cj(this) );
116 });
117
118 {/literal}{else}{literal}
119 cj('select[id^="member_option_"]').each( function() {
120 if ( cj(this).val() == 1 ) {
121 cj(this).attr('disabled', true);
122 }
123 });
124
125 // set payment info accord to membership type
126 cj( 'select[id*="_membership_type_0"]').change( function() {
127 setPaymentBlock( cj(this), null );
128 });
129
130 cj( 'select[id*="_membership_type_1"]').change( function() {
131 setPaymentBlock( cj(this), cj(this).val() );
132 });
133
134 {/literal}{/if}{literal}
135
136 // line breaks between radio buttons and checkboxes
137 cj('input.form-radio').next().after('<br />');
138 cj('input.form-checkbox').next().after('<br />');
139
140 //set the focus on first element
141 cj('#primary_contact_1').focus();
142
143 });
144
145 function setPaymentBlock( form, memType ) {
146 var rowID = form.closest('div.crm-grid-row').attr('entity_id');
147 var dataUrl = {/literal}"{crmURL p='civicrm/ajax/memType' h=0}"{literal};
148
149 if ( !memType ) {
150 memType = cj( 'select[id="field_'+ rowID+'_membership_type_1"]').val();
151 }
152
153 cj.post( dataUrl, {mtype: memType}, function( data ) {
154 cj('#field_' + rowID + '_financial_type').val( data.financial_type_id );
155 cj('#field_' + rowID + '_total_amount').val( data.total_amount ).change();
156 }, 'json');
157 }
158
159 function hideSendReceipt() {
160 cj( 'input[id*="][send_receipt]"]').each( function() {
161 showHideReceipt( cj(this) );
162 });
163 }
164
165 function showHideReceipt( elem ) {
166 var rowID = elem.closest('div.crm-grid-row').attr('entity_id');
167 var element = 'field_' + rowID + '_receipt_date';
168 if ( elem.prop('checked') ) {
169 cj('.crm-batch-receipt_date-'+ rowID ).hide();
170 } else {
171 cj('.crm-batch-receipt_date-'+ rowID ).show();
172 }
173 }
174
175 function validateRow( ) {
176 cj('.selector-rows').each(function(){
177 checkColumns( cj(this) );
178 });
179 }
180
181 function checkColumns( parentRow ) {
182 // show valid row icon if all required data is field
183 var validRow = 0;
184 var inValidRow = 0;
185 var errorExists = false;
c20ca2c8
C
186 var rowID = parentRow.closest('div.crm-grid-row').attr('entity_id');
187
6a488035 188 parentRow.find('div .required').each(function(){
c20ca2c8
C
189 //special case to handle contact autocomplete select
190 var fieldId = cj(this).attr('id');
191 if (fieldId.substring(0, 16) == 'primary_contact_') {
192 // if display value is set then make sure we also check if contact id is set
193 if ( !cj(this).val( ) ) {
194 inValidRow++;
195 }
196 else if (cj(this).val( ) && !cj('input[name="primary_contact_select_id[' + rowID + ']"]').val()) {
197 inValidRow++;
198 errorExists = true;
199 }
200 } else if ( !cj(this).val( ) ) {
6a488035
TO
201 inValidRow++;
202 } else if ( cj(this).hasClass('error') && !cj(this).hasClass('valid') ) {
203 errorExists = true;
204 } else {
205 validRow++;
206 }
207 });
208
c20ca2c8 209 // this means user has entered some data
6a488035
TO
210 if ( errorExists ) {
211 parentRow.find("div:first span").prop('class', 'batch-invalid');
212 } else if ( inValidRow == 0 && validRow > 0 ) {
213 parentRow.find("div:first span").prop('class', 'batch-valid');
214 } else {
215 parentRow.find("div:first span").prop('class', 'batch-edit');
216 }
217 }
218
219 function calculateActualTotal() {
220 var total = 0;
221 cj('input[id*="_total_amount"]').each(function(){
222 if ( cj(this).val() ) {
223 total += parseFloat(cj(this).val());
224 }
225 });
226
227 cj('.batch-actual-total').html(formatMoney(total));
228 }
229
230 //money formatting/localization
231 function formatMoney ( amount ) {
232 var c = 2;
233 var t = '{/literal}{$config->monetaryThousandSeparator}{literal}';
234 var d = '{/literal}{$config->monetaryDecimalPoint}{literal}';
235
236 var n = amount,
237 c = isNaN(c = Math.abs(c)) ? 2 : c,
238 d = d == undefined ? "," : d,
239 t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
240 i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
241 j = (j = i.length) > 3 ? j % 3 : 0;
242
243 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) : "");
244 }
245
246 function updateContactInfo( blockNo, prefix ) {
247 var contactHiddenElement = 'input[name="' + prefix + 'contact_select_id[' + blockNo +']"]';
248 var contactId = cj( contactHiddenElement ).val();;
249
250 var returnProperties = '';
251 var profileFields = new Array();
252 {/literal}
253 {if $contactFields}
254 {foreach from=$contactFields item=val key=fldName}
255 var fldName = "{$fldName}";
256 {literal}
257 if ( returnProperties ) {
258 returnProperties = returnProperties + ',';
259 }
260 var fld = fldName.split('-');
261 returnProperties = returnProperties + fld[0];
262 profileFields[fld[0]] = fldName;
263 {/literal}
264 {/foreach}
265 {/if}
266 {literal}
267
268 CRM.api('Contact','get',{
269 'sequential' :'1',
270 'contact_id': contactId,
271 'return': returnProperties },
272 { success: function (data) {
273 cj.each ( data.values[0], function( key, value ) {
274 // set the values
275 var actualFldName = profileFields[key];
276 if ( key == 'country' || key == 'state_province' ) {
277 idFldName = key + '_id';
278 value = data.values[0][idFldName];
279 }
280 setFieldValue( actualFldName, value, blockNo )
281 });
282
283 // for membership batch entry based on contact we need to enable / disable
284 // add membership select
285 {/literal}{if $batchType eq 2}{literal}
286 CRM.api('Membership','get',{
287 'sequential' :'1',
288 'contact_id': contactId,
289 },
290 { success: function (data) {
291 if ( data.count > 0 ) {
292 //get the information on membership type
293 var membershipTypeId = data.values[0].membership_type_id;
294 var membershipJoinDate = data.values[0].join_date;
295 CRM.api('MembershipType','get',{
296 'sequential' :'1',
297 'id' : membershipTypeId
298 },
299 { success: function (data){
300 var memTypeContactId = data.values[0].member_of_contact_id;
301 cj('select[id="member_option_' + blockNo + '"]').removeAttr('disabled').val(2);
302 cj('select[id="field_' + blockNo + '_membership_type_0"]').val( memTypeContactId ).change();
303 cj('select[id="field_' + blockNo + '_membership_type_1"]').val( membershipTypeId ).change();
304 setDateFieldValue( 'join_date', membershipJoinDate, blockNo )
305 }
306 });
307 }
308 }
309 });
310 {/literal}{/if}{literal}
311 }
312 });
313 }
314
315/**
316 * This function is use to setdefault elements via ajax
317 *
318 * @param fname string field name
319 * @return void
320 */
321function setFieldValue( fname, fieldValue, blockNo ) {
322 var elementId = cj('[name="field['+ blockNo +']['+ fname +']"]');
323
324 if ( elementId.length == 0 ) {
325 elementId = cj('input[type=checkbox][name^="field['+ blockNo +']['+ fname +']"][type!=hidden]');
326 }
327
328 // if element not found than return
329 if ( elementId.length == 0 ) {
330 return;
331 }
332
333 //check if it is date element
334 var isDateElement = elementId.attr('format');
335
336 // check if it is wysiwyg element
337 var editor = elementId.attr('editor');
338
339 //get the element type
340 var elementType = elementId.attr('type');
341
342 // set the value for all the elements, elements needs to be handled are
343 // select, checkbox, radio, date fields, text, textarea, multi-select
344 // wysiwyg editor, advanced multi-select ( to do )
345 if ( elementType == 'radio' ) {
346 if ( fieldValue ) {
347 elementId.filter("[value=" + fieldValue + "]").prop("checked",true);
348 } else {
349 elementId.removeProp('checked');
350 }
351 } else if ( elementType == 'checkbox' ) {
352 // handle checkbox
353 elementId.removeProp('checked');
354 if ( fieldValue ) {
355 cj.each( fieldValue, function( key, value ) {
356 cj('input[name="field['+ blockNo +']['+ fname +']['+ value +']"]').prop('checked', true);
357 });
358 }
359 } else if ( editor ) {
360 switch ( editor ) {
361 case 'ckeditor':
362 var elemtId = elementId.attr('id');
363 oEditor = CKEDITOR.instances[elemtId];
364 oEditor.setData( htmlContent );
365 break;
366 case 'tinymce':
367 var elemtId = element.attr('id');
368 tinyMCE.get( elemtId ).setContent( htmlContent );
369 break;
370 case 'joomlaeditor':
371 // TO DO
372 case 'drupalwysiwyg':
373 // TO DO
374 default:
375 elementId.val( fieldValue );
376 }
377 } else {
378 elementId.val( fieldValue );
379 }
380
381 // since we use different display field for date we also need to set it.
382 // also check for date time field and set the value correctly
383 if ( isDateElement && fieldValue ) {
384 setDateFieldValue( fname, fieldValue, blockNo )
385 }
386}
387
388function setDateFieldValue( fname, fieldValue, blockNo ) {
389 var dateValues = fieldValue.split(' ');
390
391 var actualDateElement = cj('#field_'+ blockNo +'_' + fname );
392 var date_format = actualDateElement.attr('format');
393 var altDateFormat = 'yy-mm-dd';
394
395 var actualDateValue = cj.datepicker.parseDate( altDateFormat, dateValues[0] );
396
397 // format date according to display field
398 var hiddenDateValue = cj.datepicker.formatDate( 'mm/dd/yy', actualDateValue );
399
400 actualDateElement.val( hiddenDateValue );
401
402 var displayDateValue = actualDateElement.val();
403 if ( date_format != 'mm/dd/yy' ) {
404 displayDateValue = cj.datepicker.formatDate( date_format, actualDateValue );
405 }
406
407 cj('#field_'+ blockNo +'_' + fname + '_display').val( displayDateValue );
408
409 // need to fix time formatting
410 if ( dateValues[1] ) {
411 cj('#field_'+ blockNo +'_' + fname + '_time').val(dateValues[1].substr(0,5));
412 }
413}
414
415</script>
416{/literal}
417
418{*include batch copy js js file*}
419{include file="CRM/common/batchCopy.tpl"}