CRM-15932 - Fix multi-date widget edge-case behavior
[civicrm-core.git] / templates / CRM / Core / Form / RecurringEntity.tpl
1 {*
2 +--------------------------------------------------------------------+
3 | CiviCRM version 4.6 |
4 +--------------------------------------------------------------------+
5 | Copyright CiviCRM LLC (c) 2004-2014 |
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
27 <div class="crm-core-form-recurringentity-block crm-accordion-wrapper{if $recurringFormIsEmbedded && !$scheduleReminderId} collapsed{/if}" id="recurring-entity-block">
28 <div class="crm-accordion-header">
29 {ts 1=$recurringEntityType}Repeat %1{/ts}
30 </div>
31 <div class="crm-accordion-body">
32 {if !$recurringFormIsEmbedded}
33 <div class="crm-submit-buttons">
34 {include file="CRM/common/formButtons.tpl" location="top"}
35 </div>
36 {/if}
37 <table class="form-layout-compressed">
38 <tr class="crm-core-form-recurringentity-block-repetition_start_date" id="tr-repetition_start_date">
39 <td class="label">{$form.repetition_start_date.label}</td>
40 <td>{include file="CRM/common/jcalendar.tpl" elementName=repetition_start_date}</td>
41 </tr>
42 <tr class="crm-core-form-recurringentity-block-repetition_frequency">
43 <td class="label">{$form.repetition_frequency_unit.label}&nbsp;<span class="crm-marker">*</span> {help id="id-repeats" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
44 <td>{$form.repetition_frequency_interval.html} {$form.repetition_frequency_unit.html}</td>
45 </tr>
46 <tr class="crm-core-form-recurringentity-block-start_action_condition">
47 <td class="label">
48 <label for="repeats_on">{$form.start_action_condition.label} {help id="id-repeats-on" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</label>
49 </td>
50 <td>
51 {$form.start_action_condition.html}
52 </td>
53 </tr>
54 <tr class="crm-core-form-recurringentity-block-repeats_by">
55 <td class="label">{$form.repeats_by.label} {help id="id-repeats-by-month" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
56 <td>{$form.repeats_by.1.html}&nbsp;&nbsp;{$form.limit_to.html}
57 </td>
58 </tr>
59 <tr class="crm-core-form-recurringentity-block-repeats_by">
60 <td class="label">{help id="id-repeats-by-week" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
61 <td>{$form.repeats_by.2.html}&nbsp;&nbsp;{$form.entity_status_1.html}&nbsp;&nbsp;{$form.entity_status_2.html}
62 </td>
63 </tr>
64 <tr class="crm-core-form-recurringentity-block-ends">
65 <td class="label">{$form.ends.label}&nbsp;<span class="crm-marker">*</span> {help id="id-ends-after" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
66 <td>{$form.ends.1.html}&nbsp;{$form.start_action_offset.html} {ts}occurrences{/ts}</td>
67 </tr>
68 <tr class="crm-core-form-recurringentity-block-absolute_date">
69 <td class="label"> {help id="id-ends-on" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
70 <td>{$form.ends.2.html}&nbsp;{include file="CRM/common/jcalendar.tpl" elementName=repeat_absolute_date}
71 </td>
72 </tr>
73 <tr class="crm-core-form-recurringentity-block-exclude_date">
74 <td class="label">{$form.exclude_date_list.label} {help id="id-exclude-date" entityType=$recurringEntityType file="CRM/Core/Form/RecurringEntity.hlp"}</td>
75 <td>{$form.exclude_date_list.html}</td>
76 </tr>
77 </table>
78 {if !$recurringFormIsEmbedded}
79 <div class="crm-submit-buttons">
80 {include file="CRM/common/formButtons.tpl" location="bottom"}
81 </div>
82 {/if}
83 </div>
84 </div>
85 {literal}
86 <script type="text/javascript">
87 (function (_) {
88 CRM.$(function($) {
89 var $form = $('form.{/literal}{$form.formClass}{literal}'),
90 defaultDate = null;
91
92 // Prevent html5 errors
93 $form.attr('novalidate', 'novalidate');
94
95 function changeFrequencyUnit() {
96 switch ($(this).val()) {
97 case 'week':
98 //Show "Repeats On" block when week is selected
99 $('.crm-core-form-recurringentity-block-start_action_condition', $form).show();
100 $('.crm-core-form-recurringentity-block-repeats_by td', $form).hide();
101 break;
102 case 'month':
103 //Show "Repeats By" block when month is selected
104 $('.crm-core-form-recurringentity-block-start_action_condition', $form).hide();
105 $('.crm-core-form-recurringentity-block-repeats_by td', $form).show();
106 break;
107 default:
108 $('.crm-core-form-recurringentity-block-start_action_condition', $form).hide();
109 $('.crm-core-form-recurringentity-block-repeats_by td', $form).hide();
110 }
111 }
112 $('#repetition_frequency_unit', $form).each(changeFrequencyUnit).change(changeFrequencyUnit);
113
114 function disableUnselected() {
115 $('input:radio[name=ends], input[name=repeats_by]', $form).not(':checked').siblings(':input').prop('disabled', true).removeClass('required');
116 }
117 disableUnselected();
118
119 $('input:radio[name=ends], input[name=repeats_by]', $form).click(function() {
120 $(this).siblings(':input').prop('disabled', false).filter(':visible').addClass('required').focus();
121 disableUnselected();
122 });
123
124 $('input:radio[name=ends]').siblings('.crm-clear-link').click(function() {
125 $('input:radio[name=ends][value=1]').prop('checked', true).trigger('click');
126 });
127
128 function validate() {
129 var valid = $(':input', '#recurring-entity-block').valid(),
130 modified = CRM.utils.initialValueChanged('#recurring-entity-block');
131 $('#allowRepeatConfigToSubmit', $form).val(valid && modified ? '1' : '0');
132 return valid;
133 }
134
135 function getDisplayDate(date) {
136 return $.datepicker.formatDate(CRM.config.dateInputFormat, $.datepicker.parseDate('yy-mm-dd', date));
137 }
138
139 // Combine select2 and datepicker into a multi-select-date widget
140 $('#exclude_date_list', $form).crmSelect2({
141 multiple: true,
142 data: [],
143 initSelection: function(element, callback) {
144 var values = [];
145 $.each($(element).val().split(','), function(k, v) {
146 values.push({
147 text: getDisplayDate(v),
148 id: v
149 });
150 });
151 callback(values);
152 }
153 })
154 .on('select2-opening', function(e) {
155 var $el = $(this),
156 $input = $('.select2-search-field input', $el.select2('container'));
157 // Prevent select2 from opening and show a datepicker instead
158 e.preventDefault();
159 if (!$input.data('datepicker')) {
160 $input
161 .datepicker({
162 beforeShow: function() {
163 var existingSelections = _.pluck($el.select2('data') || [], 'id');
164 return {
165 changeMonth: true,
166 changeYear: true,
167 defaultDate: defaultDate,
168 beforeShowDay: function(date) {
169 // Don't allow the same date to be selected twice
170 var dateStr = $.datepicker.formatDate('yy-mm-dd', date);
171 if (_.includes(existingSelections, dateStr)) {
172 return [false, '', '{/literal}{ts escape='js'}Already selected{/ts}{literal}'];
173 }
174 return [true, '', ''];
175 }
176 };
177 }
178 })
179 .datepicker('show')
180 .on('change.crmDate', function() {
181 if ($(this).val()) {
182 var date = defaultDate = $(this).datepicker('getDate'),
183 data = $el.select2('data') || [];
184 data.push({
185 text: $.datepicker.formatDate(CRM.config.dateInputFormat, date),
186 id: $.datepicker.formatDate('yy-mm-dd', date)
187 });
188 $el.select2('data', data, true);
189 }
190 })
191 .on('keyup', function() {
192 $(this).val('').datepicker('show');
193 });
194 }
195 })
196 // Don't leave datepicker open when clearing selections
197 .on('select2-removed', function() {
198 $('input.hasDatepicker', $(this).select2('container'))
199 .datepicker('hide');
200 });
201
202
203 // Dialog for preview repeat Configuration dates
204 function previewDialog() {
205 // Set default value for start date on activity forms before generating preview
206 if (!$('#repetition_start_date', $form).val() && $('#activity_date_time', $form).val()) {
207 $('#repetition_start_date', $form)
208 .val($('#activity_date_time', $form).val())
209 .next().val($('#activity_date_time', $form).next().val())
210 .siblings('.hasTimeEntry').val($('#activity_date_time', $form).siblings('.hasTimeEntry').val());
211 }
212 var payload = $form.serialize() + '{/literal}&entity_table={$entityTable}&entity_id={$currentEntityId}{literal}';
213 CRM.confirm({
214 width: '50%',
215 url: CRM.url("civicrm/recurringentity/preview", payload)
216 }).on('crmConfirm:yes', function() {
217 $form.submit();
218 });
219 }
220
221 $('#_qf_Repeat_submit-top, #_qf_Repeat_submit-bottom').click(function (e) {
222 if (validate()) {
223 previewDialog();
224 }
225 e.preventDefault();
226 });
227
228 $('#_qf_Activity_upload-top, #_qf_Activity_upload-bottom').click(function (e) {
229 if (CRM.utils.initialValueChanged('#recurring-entity-block')) {
230 e.preventDefault();
231 if (validate()) {
232 previewDialog();
233 }
234 }
235 });
236
237 // Enable/disable form buttons when not embedded in another form
238 $form.on('change', function() {
239 $('#_qf_Repeat_submit-top, #_qf_Repeat_submit-bottom').prop('disabled', !CRM.utils.initialValueChanged('#recurring-entity-block'));
240 });
241
242 // Pluralize frequency options
243 var recurringFrequencyOptions = {/literal}{$recurringFrequencyOptions|@json_encode}{literal};
244 function pluralizeUnits() {
245 CRM.utils.setOptions($('[name=repetition_frequency_unit]', $form),
246 $(this).val() === '1' ? recurringFrequencyOptions.single : recurringFrequencyOptions.plural);
247 }
248 $('[name=repetition_frequency_interval]', $form).each(pluralizeUnits).change(pluralizeUnits);
249
250 });
251 })(CRM._);
252 </script>
253 {/literal}