Merge pull request #5273 from colemanw/CRM-16007
[civicrm-core.git] / templates / CRM / Contact / Page / View / Summary.js
1 // http://civicrm.org/licensing
2 (function($, _) {
3
4 var ajaxFormParams = {
5 dataType:'json',
6 beforeSubmit: function(arr, $form, options) {
7 $form.block();
8 },
9 success: requestHandler,
10 error: errorHandler
11 };
12
13 function crmFormInline(o) {
14 var data = o.data('edit-params');
15 if (o.is('.crm-edit-ready .crm-inline-edit') && data) {
16 o.animate({height: '+=50px'}, 200);
17 data.snippet = 6;
18 data.reset = 1;
19 o.addClass('form');
20 $('.crm-edit-ready').removeClass('crm-edit-ready');
21 o.block();
22 $.getJSON(CRM.url('civicrm/ajax/inline', data))
23 .fail(errorHandler)
24 .done(function(response) {
25 o.unblock();
26 o.css('overflow', 'hidden').wrapInner('<div class="inline-edit-hidden-content" style="display:none" />').append(response.content);
27 // Smooth resizing
28 var newHeight = $('.crm-container-snippet', o).height();
29 var diff = newHeight - parseInt(o.css('height'), 10);
30 if (diff < 0) {
31 diff = 0 - diff;
32 }
33 o.animate({height: '' + newHeight + 'px'}, diff * 2, function() {
34 o.removeAttr('style');
35 });
36 $('form', o).validate(CRM.validate.params);
37 ajaxFormParams.data = data;
38 $('form', o).ajaxForm(ajaxFormParams);
39 o.trigger('crmLoad').trigger('crmFormLoad');
40 });
41 }
42 }
43
44 function reloadBlock(el) {
45 return $(el).each(function() {
46 var data = $(this).data('edit-params');
47 data.snippet = data.reset = 1;
48 data.class_name = data.class_name.replace('Form', 'Page');
49 data.type = 'page';
50 $(this).closest('.crm-summary-block').load(CRM.url('civicrm/ajax/inline', data), function() {$(this).trigger('crmLoad');});
51 });
52 }
53
54 function requestHandler(response) {
55 var o = $('div.crm-inline-edit.form');
56 $('form', o).ajaxFormUnbind();
57
58 if (response.status == 'success' || response.status == 'cancel') {
59 o.trigger('crmFormSuccess', [response]);
60 $('.crm-inline-edit-container').addClass('crm-edit-ready');
61 var data = o.data('edit-params');
62 var dependent = $((o.data('dependent-fields') || []).join(','));
63 // Clone the add-new link if replacing it, and queue the clone to be refreshed as a dependent block
64 if (o.hasClass('add-new') && response.addressId) {
65 data.aid = response.addressId;
66 var clone = o.closest('.crm-summary-block').clone();
67 o.data('edit-params', data);
68 $('form', clone).remove();
69 if (clone.hasClass('contactCardLeft')) {
70 clone.removeClass('contactCardLeft').addClass('contactCardRight');
71 }
72 else if (clone.hasClass('contactCardRight')) {
73 clone.removeClass('contactCardRight').addClass('contactCardLeft');
74 }
75 var cl = $('.crm-inline-edit', clone);
76 var clData = cl.data('edit-params');
77 var locNo = clData.locno++;
78 cl.attr('id', cl.attr('id').replace(locNo, clData.locno)).removeClass('form');
79 o.closest('.crm-summary-block').after(clone);
80 dependent = dependent.add($('.crm-inline-edit', clone));
81 }
82 $('a.ui-notify-close', '#crm-notification-container').click();
83 // Delete an address
84 if (o.hasClass('address') && !o.hasClass('add-new') && !response.addressId) {
85 o.parent().remove();
86 CRM.status(ts('Address Deleted'));
87 }
88 else {
89 // Reload this block plus all dependent blocks
90 reloadBlock(dependent.add(o));
91 CRM.status(ts('Saved'));
92 }
93 }
94 else {
95 // Handle formRule error
96 $('.crm-container-snippet', o).replaceWith(response.content);
97 $('form', o).validate(CRM.validate.params);
98 $('form', o).ajaxForm(ajaxFormParams);
99 o.trigger('crmFormError', [response]).trigger('crmFormLoad').trigger('crmLoad');
100 }
101 }
102
103 /**
104 * Configure optimistic locking mechanism for inplace editing
105 *
106 * options.ignoreLabel: string, text for a button
107 * options.reloadLabel: string, text for a button
108 */
109 $.fn.crmFormContactLock = function(options) {
110 var form = this;
111 // AFTER ERROR: Render any "Ignore" and "Restart" buttons
112 return this.on('crmFormError', function(event, obj, status) {
113 var o = $(event.target);
114 var data = o.data('edit-params');
115 var errorTag = o.find('.update_oplock_ts');
116 if (errorTag.length > 0) {
117 $('<span>')
118 .addClass('crm-lock-button css_right')
119 .appendTo(errorTag);
120
121 var buttonContainer = o.find('.crm-lock-button');
122 $('<button>')
123 .addClass('crm-button')
124 .text(options.saveAnywayLabel)
125 .click(function() {
126 $(form).find('input[name=oplock_ts]').val(errorTag.attr('data:update_oplock_ts'));
127 errorTag.parent().hide();
128 $(this).closest('form').find('.crm-form-submit.default').first().click();
129 return false;
130 })
131 .appendTo(buttonContainer)
132 ;
133 $('<button>')
134 .addClass('crm-button')
135 .text(options.reloadLabel)
136 .click(function() {
137 window.location.reload();
138 return false;
139 })
140 .appendTo(buttonContainer)
141 ;
142 }
143 });
144 };
145
146 function errorHandler(response) {
147 CRM.alert(ts('Unable to reach the server. Please refresh this page in your browser and try again.'), ts('Network Error'), 'error');
148 $('.crm-inline-edit.form form').unblock();
149 }
150
151 $(function() {
152 // don't perform inline edit during print mode
153 if (CRM.summaryPrint.mode) {
154 $('div').removeClass('crm-inline-edit');
155 $('.crm-inline-block-content > div.crm-edit-help').remove();
156 $('div.crm-inline-block-content').removeAttr('title');
157 }
158 // Set page title
159 var oldName = 'CiviCRM';
160 var nameTitle = $('#crm-remove-title');
161 if (nameTitle.length > 0) {
162 oldName = nameTitle.text();
163 nameTitle.parent('h1').remove();
164 }
165 else {
166 $('h1').each(function() {
167 if ($(this).text() == oldName) {
168 $(this).remove();
169 }
170 });
171 }
172 function refreshTitle() {
173 var contactName = $('.crm-summary-display_name').text();
174 contactName = $.trim(contactName);
175 document.title = $('title').html().replace(oldName, contactName);
176 oldName = contactName;
177 }
178 $('#contactname-block').load(refreshTitle);
179 refreshTitle();
180
181 var clicking;
182 $('.crm-inline-edit-container')
183 .addClass('crm-edit-ready')
184 // Allow links inside edit blocks to be clicked without triggering edit
185 .on('mousedown', '.crm-inline-edit:not(.form) a, .crm-inline-edit:not(.form) .crm-accordion-header, .crm-inline-edit:not(.form) .collapsible-title', function(event) {
186 if (event.which == 1) {
187 event.stopPropagation();
188 return false;
189 }
190 })
191 // Respond to a click (not drag, not right-click) of crm-inline-edit blocks
192 .on('mousedown', '.crm-inline-edit:not(.form)', function(button) {
193 if (button.which == 1) {
194 clicking = this;
195 setTimeout(function() {clicking = null;}, 500);
196 }
197 })
198 .on('mouseup', '.crm-inline-edit:not(.form)', function(button) {
199 if (clicking === this && button.which == 1) {
200 crmFormInline($(this));
201 }
202 })
203 // Inline edit form cancel button
204 .on('click', '.crm-inline-edit :submit[name$=cancel]', function() {
205 var container = $(this).closest('.crm-inline-edit.form');
206 $('form', container).ajaxFormUnbind();
207 $('.inline-edit-hidden-content', container).nextAll().remove();
208 $('.inline-edit-hidden-content > *:first-child', container).unwrap();
209 container.removeClass('form');
210 $('.crm-inline-edit-container').addClass('crm-edit-ready');
211 $('a.ui-notify-close', '#crm-notification-container').click();
212 return false;
213 })
214 // Switch tabs when clicking tag link
215 .on('click', '#tagLink a', function() {
216 $('#tab_tag a').click();
217 return false;
218 })
219 // make sure only one is_primary radio is checked
220 .on('change', '[class$=is_primary] input', function() {
221 if ($(this).is(':checked')) {
222 $('[class$=is_primary] input', $(this).closest('form')).not(this).prop('checked', false);
223 }
224 })
225 // make sure only one builk_mail radio is checked
226 .on('change', '.crm-email-bulkmail input', function(){
227 if ($(this).is(':checked')) {
228 $('.crm-email-bulkmail input').not(this).prop('checked', false);
229 }
230 })
231 // handle delete link within blocks
232 .on('click', '.crm-delete-inline', function(e) {
233 var row = $(this).closest('tr');
234 var form = $(this).closest('form');
235 row.hide();
236 $('input', row).val('');
237 //if the primary is checked for deleted block
238 //unset and set first as primary
239 if ($('[class$=is_primary] input:checked', row).length > 0) {
240 $('[class$=is_primary] input', row).prop('checked', false);
241 $('[class$=is_primary] input:first', form).prop('checked', true );
242 }
243 $('.add-more-inline', form).show();
244 e.preventDefault();
245 })
246 // Delete an address
247 .on('click', '.crm-inline-edit.address .delete-button', function(e) {
248 var $block = $(this).closest('.crm-inline-edit.address');
249 CRM.confirm({message: ts('Are you sure you want to delete this address?')})
250 .on('crmConfirm:yes', function() {
251 CRM.api3('address', 'delete', {id: $block.data('edit-params').aid}, true)
252 .done(function(data) {
253 $('.crm-inline-edit-container').addClass('crm-edit-ready');
254 $block.remove();
255 reloadBlock('.crm-inline-edit.address:not(.add-new)');
256 });
257 });
258 e.preventDefault();
259 })
260 // add more and set focus to new row
261 .on('click', '.add-more-inline', function(e) {
262 var form = $(this).closest('form');
263 var row = $('tr[class="hiddenElement"]:first', form);
264 row.removeClass('hiddenElement');
265 $('input:focus', form).blur();
266 $('input:first', row).focus();
267 if ($('tr[class="hiddenElement"]').length < 1) {
268 $(this).hide();
269 }
270 e.preventDefault();
271 });
272 // Trigger cancel button on esc keypress
273 $(document).keydown(function(key) {
274 if (key.which == 27) {
275 $('.crm-inline-edit.form :submit[name$=cancel]').click();
276 }
277 });
278 $('#crm-container')
279 // Switch tabs when clicking log link
280 .on('click', '#crm-record-log a.crm-log-view', function() {
281 $('#tab_log a').click();
282 return false;
283 })
284 // Handle action links in popup
285 .on('click', '.crm-contact_actions-list a, .crm-contact_activities-list a', function(e) {
286 $('#crm-contact-actions-list').hide();
287 if ($(this).attr('href') === '#') {
288 var $tab = $('#tab_' + ($(this).data('tab') || 'summary'));
289 CRM.tabHeader.focus($tab);
290 e.preventDefault();
291 } else {
292 CRM.popup.call(this, e);
293 }
294 })
295 .on('crmPopupFormSuccess', '.crm-contact_actions-list a, .crm-contact_activities-list a', function() {
296 var $tab = $('#tab_' + ($(this).data('tab') || 'summary'));
297 CRM.tabHeader.resetTab($tab);
298 CRM.tabHeader.focus($tab);
299 });
300 $(document)
301 // Actions menu
302 .on('click', function(e) {
303 if ($(e.target).is('#crm-contact-actions-link, #crm-contact-actions-link *')) {
304 $('#crm-contact-actions-list').show();
305 return false;
306 }
307 $('#crm-contact-actions-list').hide();
308 })
309 .on('crmFormSuccess crmLoad', function(e, data) {
310 // Update changelog tab and contact footer
311 if (data && data.changeLog) {
312 if (data.changeLog.count) {
313 CRM.tabHeader.updateCount('#tab_log', data.changeLog.count);
314 }
315 if (data.changeLog.markup) {
316 $("#crm-record-log").replaceWith(data.changeLog.markup);
317 }
318 }
319 })
320 .on('crmFormSuccess', function(e, data) {
321 // Refresh changeLog - advanced logging
322 if (CRM.reloadChangeLogTab) {
323 CRM.reloadChangeLogTab();
324 }
325 // Refresh changeLog - simple logging
326 // If we didn't get a changelog count in the response, force refresh the changelog tab to populate it
327 else {
328 CRM.tabHeader.resetTab('#tab_log', !(data && data.changeLog && data.changeLog.count));
329 }
330 // Refresh dependent blocks
331 if (data && data.reloadBlocks) {
332 reloadBlock(data.reloadBlocks.join(','));
333 }
334 });
335 });
336 })(CRM.$, CRM._);