1 // http://civicrm.org/licensing
3 // FIXME: Much of this code is redundant with CRM.loadForm
7 beforeSubmit: function(arr
, $form
, options
) {
10 success
: requestHandler
,
14 function crmFormInline(o
) {
15 var data
= o
.data('edit-params');
16 if (o
.is('.crm-edit-ready .crm-inline-edit') && data
) {
17 o
.animate({height
: '+=50px'}, 200);
20 var width
= o
.width();
21 $('.crm-edit-ready').removeClass('crm-edit-ready');
22 o
.block().addClass('form').css('width', '' + width
+ 'px');
23 $.getJSON(CRM
.url('civicrm/ajax/inline', data
))
25 .done(function(response
) {
27 o
.css('overflow', 'hidden').wrapInner('<div class="inline-edit-hidden-content" style="display:none" />').append(response
.content
);
28 // Needed to accurately measure box width
29 $('.crm-container-snippet', o
).css('display', 'inline-block');
31 var newHeight
= $('.crm-container-snippet', o
).height(),
32 speed
= newHeight
- parseInt(o
.css('height'), 10),
33 animation
= {height
: '' + newHeight
+ 'px'};
34 // Animation speed is set relative to how much the box needs to grow
39 var newWidth
= $('.crm-container-snippet', o
).width();
40 if (newWidth
> width
) {
41 animation
.width
= '' + newWidth
+ 'px';
42 // Slow down animation if we have lots of horizontal growth to do
43 if (newWidth
- width
> speed
) {
44 speed
= newWidth
- width
;
49 $('.crm-container-snippet', o
).css('display', '');
50 o
.animate(animation
, speed
, function() {
51 o
.css({height
: '', width
: '', minWidth
: '' + newWidth
+ 'px'});
53 $('form', o
).validate(CRM
.validate
.params
);
54 ajaxFormParams
.data
= data
;
55 $('form', o
).ajaxForm(ajaxFormParams
);
56 o
.trigger('crmLoad').trigger('crmFormLoad');
61 function reloadBlock(el
) {
62 return $(el
).each(function() {
63 var data
= $(this).data('edit-params');
65 data
.snippet
= data
.reset
= 1;
66 data
.class_name
= data
.class_name
.replace('Form', 'Page');
68 $(this).closest('.crm-summary-block').load(CRM
.url('civicrm/ajax/inline', data
), function() {
69 $(this).trigger('crmLoad');
75 function requestHandler(response
) {
76 var o
= $('div.crm-inline-edit.form');
77 $('form', o
).ajaxFormUnbind();
79 if (response
.status
== 'success' || response
.status
== 'cancel') {
80 o
.trigger('crmFormSuccess', [response
]).removeAttr('style');
81 $('.crm-inline-edit-container').addClass('crm-edit-ready');
82 var data
= o
.data('edit-params');
83 var dependent
= $((o
.data('dependent-fields') || []).join(','));
84 // Clone the add-new link if replacing it, and queue the clone to be refreshed as a dependent block
85 if (o
.hasClass('add-new') && response
.addressId
) {
86 data
.aid
= response
.addressId
;
87 var clone
= o
.closest('.crm-summary-block').clone();
88 o
.data('edit-params', data
);
89 $('form', clone
).remove();
90 if (clone
.hasClass('contactCardLeft')) {
91 clone
.removeClass('contactCardLeft').addClass('contactCardRight');
93 else if (clone
.hasClass('contactCardRight')) {
94 clone
.removeClass('contactCardRight').addClass('contactCardLeft');
96 var cl
= $('.crm-inline-edit', clone
);
97 var clData
= cl
.data('edit-params');
98 var locNo
= clData
.locno
++;
99 cl
.attr('id', cl
.attr('id').replace(locNo
, clData
.locno
)).removeClass('form');
100 o
.closest('.crm-summary-block').after(clone
);
101 dependent
= dependent
.add($('.crm-inline-edit', clone
));
103 $('a.ui-notify-close', '#crm-notification-container').click();
105 if (o
.hasClass('address') && !o
.hasClass('add-new') && !response
.addressId
) {
107 CRM
.status(ts('Address Deleted'));
110 // Reload this block plus all dependent blocks
111 reloadBlock(dependent
.add(o
));
112 CRM
.status(ts('Saved'));
116 // Handle formRule error
117 $('.crm-container-snippet', o
).replaceWith(response
.content
);
118 $('form', o
).validate(CRM
.validate
.params
);
119 $('form', o
).ajaxForm(ajaxFormParams
);
120 o
.trigger('crmFormError', [response
]).trigger('crmFormLoad').trigger('crmLoad');
125 * Configure optimistic locking mechanism for inplace editing
127 * options.ignoreLabel: string, text for a button
128 * options.reloadLabel: string, text for a button
130 $.fn
.crmFormContactLock = function(options
) {
132 // AFTER ERROR: Render any "Ignore" and "Restart" buttons
133 return this.on('crmFormError', function(event
, obj
, status
) {
134 var o
= $(event
.target
);
135 var data
= o
.data('edit-params');
136 var errorTag
= o
.find('.update_oplock_ts');
137 if (errorTag
.length
> 0) {
139 .addClass('crm-lock-button css_right')
142 var buttonContainer
= o
.find('.crm-lock-button');
144 .addClass('crm-button')
145 .text(options
.saveAnywayLabel
)
147 $(form
).find('input[name=oplock_ts]').val(errorTag
.attr('data:update_oplock_ts'));
148 errorTag
.parent().hide();
149 $(this).closest('form').find('.crm-form-submit.default').first().click();
152 .appendTo(buttonContainer
)
155 .addClass('crm-button')
156 .text(options
.reloadLabel
)
158 window
.location
.reload();
161 .appendTo(buttonContainer
)
167 function errorHandler(response
) {
168 CRM
.alert(ts('Unable to reach the server. Please refresh this page in your browser and try again.'), ts('Network Error'), 'error');
169 $('.crm-inline-edit.form form').unblock();
173 // don't perform inline edit during print mode
174 if (CRM
.summaryPrint
.mode
) {
175 $('div').removeClass('crm-inline-edit');
176 $('.crm-inline-block-content > div.crm-edit-help').remove();
177 $('div.crm-inline-block-content').removeAttr('title');
180 var oldName
= 'CiviCRM';
181 var nameTitle
= $('#crm-remove-title');
182 if (nameTitle
.length
> 0) {
183 oldName
= nameTitle
.text();
184 nameTitle
.parent('h1').remove();
187 $('h1').each(function() {
188 if ($(this).text() == oldName
) {
193 function refreshTitle() {
194 var contactName
= $('.crm-summary-display_name').text();
195 contactName
= $.trim(contactName
);
196 document
.title
= $('title').html().replace(oldName
, contactName
);
197 oldName
= contactName
;
199 $('#contactname-block').on('load', refreshTitle
);
203 $('.crm-inline-edit-container')
204 .addClass('crm-edit-ready')
205 // Allow links inside edit blocks to be clicked without triggering edit
206 .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
) {
207 if (event
.which
== 1) {
208 event
.stopPropagation();
212 // Respond to a click (not drag, not right-click) of crm-inline-edit blocks
213 .on('mousedown', '.crm-inline-edit:not(.form)', function(button
) {
214 if (button
.which
== 1) {
216 setTimeout(function() {clicking
= null;}, 500);
219 .on('mouseup', '.crm-inline-edit:not(.form)', function(button
) {
220 if (clicking
=== this && button
.which
== 1) {
221 crmFormInline($(this));
224 // Inline edit form cancel button
225 .on('click', '.crm-inline-edit :submit[name$=cancel]', function() {
226 var container
= $(this).closest('.crm-inline-edit.form');
227 $('form', container
).ajaxFormUnbind();
228 $('.inline-edit-hidden-content', container
).nextAll().remove();
229 $('.inline-edit-hidden-content > *:first-child', container
).unwrap();
230 container
.removeClass('form').removeAttr('style');
231 $('.crm-inline-edit-container').addClass('crm-edit-ready');
232 $('a.ui-notify-close', '#crm-notification-container').click();
235 // Switch tabs when clicking tag link
236 .on('click', '#tagLink a', function() {
237 $('#tab_tag a').click();
240 // make sure only one is_primary radio is checked
241 .on('change', '[class$=is_primary] input', function() {
242 if ($(this).is(':checked')) {
243 $('[class$=is_primary] input', $(this).closest('form')).not(this).prop('checked', false);
246 // make sure only one builk_mail radio is checked
247 .on('change', '.crm-email-bulkmail input', function(){
248 if ($(this).is(':checked')) {
249 $('.crm-email-bulkmail input').not(this).prop('checked', false);
252 // handle delete link within blocks
253 .on('click', '.crm-delete-inline', function(e
) {
254 var row
= $(this).closest('tr');
255 var form
= $(this).closest('form');
257 $('input', row
).val('');
258 //if the primary is checked for deleted block
259 //unset and set first as primary
260 if ($('[class$=is_primary] input:checked', row
).length
> 0) {
261 $('[class$=is_primary] input', row
).prop('checked', false);
262 $('[class$=is_primary] input:first', form
).prop('checked', true );
264 $('.add-more-inline', form
).show();
268 .on('click', '.crm-inline-edit.address .delete-button', function(e
) {
269 var $block
= $(this).closest('.crm-inline-edit.address');
270 CRM
.confirm({message
: ts('Are you sure you want to delete this address?')})
271 .on('crmConfirm:yes', function() {
272 CRM
.api3('address', 'delete', {id
: $block
.data('edit-params').aid
}, true)
273 .done(function(data
) {
274 $('.crm-inline-edit-container').addClass('crm-edit-ready');
275 $block
.closest('.crm-address-block').remove();
276 reloadBlock('.crm-inline-edit.address:not(.add-new)');
281 // add more and set focus to new row
282 .on('click', '.add-more-inline', function(e
) {
283 var form
= $(this).closest('form');
284 var row
= $('tr[class="hiddenElement"]:first', form
);
285 row
.removeClass('hiddenElement');
286 $('input:focus', form
).blur();
287 $('input:first', row
).focus();
288 if ($('tr[class="hiddenElement"]').length
< 1) {
293 // Trigger cancel button on esc keypress
294 $(document
).keydown(function(key
) {
295 if (key
.which
== 27) {
296 $('.crm-inline-edit.form :submit[name$=cancel]').click();
300 // Switch tabs when clicking log link
301 .on('click', '#crm-record-log a.crm-log-view', function() {
302 $('#tab_log a').click();
305 // Handle action links in popup
306 .on('click', '.crm-contact_actions-list a, .crm-contact_activities-list a', function(e
) {
307 $('#crm-contact-actions-list').hide();
308 if ($(this).attr('href') === '#') {
309 var $tab
= $('#tab_' + ($(this).data('tab') || 'summary'));
310 CRM
.tabHeader
.focus($tab
);
313 CRM
.popup
.call(this, e
);
316 .on('crmPopupFormSuccess', '.crm-contact_actions-list a, .crm-contact_activities-list a', function() {
317 var $tab
= $('#tab_' + ($(this).data('tab') || 'summary'));
318 CRM
.tabHeader
.resetTab($tab
);
319 CRM
.tabHeader
.focus($tab
);
323 .on('click', function(e
) {
324 if ($(e
.target
).is('#crm-contact-actions-link, #crm-contact-actions-link *')) {
325 $('#crm-contact-actions-list').show();
328 $('#crm-contact-actions-list').hide();
330 .on('crmFormSuccess crmLoad', function(e
, data
) {
331 // Update changelog tab and contact footer
332 if (data
&& data
.changeLog
) {
333 if (data
.changeLog
.count
) {
334 CRM
.tabHeader
.updateCount('#tab_log', data
.changeLog
.count
);
336 if (data
.changeLog
.markup
) {
337 $("#crm-record-log").replaceWith(data
.changeLog
.markup
);
341 .on('crmFormSuccess', function(e
, data
) {
342 // Advanced logging... just increment the changelog tab count to avoid the overhead of reloading the data
343 if (CRM
.incrementChangeLogTab
) {
344 CRM
.incrementChangeLogTab();
346 // Refresh changelog tab next time it is opened
347 CRM
.tabHeader
.resetTab('#tab_log');
348 // Refresh dependent blocks
349 if (data
&& data
.reloadBlocks
) {
350 reloadBlock(data
.reloadBlocks
.join(','));
355 * Make contact summary fit in small screens
357 function onResize() {
358 var contactwidth
= $('#crm-container #mainTabContainer').width();
359 if (contactwidth
< 600) {
360 $('#crm-container #mainTabContainer').addClass('narrowpage');
361 $('#crm-container #mainTabContainer.narrowpage #contactTopBar td').each(function (index
) {
363 if (index
% 2 === 0) {
364 $(this).parent().after('<tr class="narrowadded"></tr>');
367 $(this).parent().next().append(item
);
372 $('#crm-container #mainTabContainer.narrowpage').removeClass('narrowpage');
373 $('#crm-container #mainTabContainer #contactTopBar tr.narrowadded td').each(function () {
375 var parent
= $(this).parent();
376 $(this).parent().prev().append(nitem
);
377 if (parent
.children().size() === 0) {
381 $('#crm-container #mainTabContainer.narrowpage #contactTopBar tr.added').detach();
383 var cformwidth
= $('#crm-container #Contact .contact_basic_information-section').width();
385 if (cformwidth
< 720) {
386 $('#crm-container .contact_basic_information-section').addClass('narrowform');
387 $('#crm-container .contact_basic_information-section table.form-layout-compressed td .helpicon').parent().addClass('hashelpicon');
388 if (cformwidth
< 480) {
389 $('#crm-container .contact_basic_information-section').addClass('xnarrowform');
392 $('#crm-container .contact_basic_information-section.xnarrowform').removeClass('xnarrowform');
396 $('#crm-container .contact_basic_information-section.narrowform').removeClass('narrowform');
397 $('#crm-container .contact_basic_information-section.xnarrowform').removeClass('xnarrowform');
402 $(window
).resize(onResize
);