1 // http://civicrm.org/licensing
3 // FIXME: Much of this code is redundant with CRM.loadForm
7 beforeSubmit: function(arr
, $form
, options
) {
10 beforeSerialize: function(form
, options
) {
11 // Copied from crm.ajax.js
12 if (window
.CKEDITOR
&& window
.CKEDITOR
.instances
) {
13 $.each(CKEDITOR
.instances
, function() {
14 if (this.updateElement
) this.updateElement();
17 if (window
.tinyMCE
&& tinyMCE
.editors
) {
18 $.each(tinyMCE
.editors
, function() {
23 success
: requestHandler
,
27 function crmFormInline(o
) {
28 var data
= o
.data('edit-params');
29 if (o
.is('.crm-edit-ready .crm-inline-edit') && data
) {
30 o
.animate({height
: '+=50px'}, 200);
34 $('.crm-edit-ready').removeClass('crm-edit-ready');
36 $.getJSON(CRM
.url('civicrm/ajax/inline', data
))
38 .done(function(response
) {
40 o
.css('overflow', 'hidden').wrapInner('<div class="inline-edit-hidden-content" style="display:none" />').append(response
.content
);
42 var newHeight
= $('.crm-container-snippet', o
).height();
43 var diff
= newHeight
- parseInt(o
.css('height'), 10);
47 o
.animate({height
: '' + newHeight
+ 'px'}, diff
* 2, function() {
48 o
.removeAttr('style');
50 $('form', o
).validate(CRM
.validate
.params
);
51 ajaxFormParams
.data
= data
;
52 $('form', o
).ajaxForm(ajaxFormParams
);
53 o
.trigger('crmLoad').trigger('crmFormLoad');
58 function reloadBlock(el
) {
59 return $(el
).each(function() {
60 var data
= $(this).data('edit-params');
61 data
.snippet
= data
.reset
= 1;
62 data
.class_name
= data
.class_name
.replace('Form', 'Page');
64 $(this).closest('.crm-summary-block').load(CRM
.url('civicrm/ajax/inline', data
), function() {$(this).trigger('crmLoad');});
68 function requestHandler(response
) {
69 var o
= $('div.crm-inline-edit.form');
70 $('form', o
).ajaxFormUnbind();
72 if (response
.status
== 'success' || response
.status
== 'cancel') {
73 o
.trigger('crmFormSuccess', [response
]);
74 $('.crm-inline-edit-container').addClass('crm-edit-ready');
75 var data
= o
.data('edit-params');
76 var dependent
= $((o
.data('dependent-fields') || []).join(','));
77 // Clone the add-new link if replacing it, and queue the clone to be refreshed as a dependent block
78 if (o
.hasClass('add-new') && response
.addressId
) {
79 data
.aid
= response
.addressId
;
80 var clone
= o
.closest('.crm-summary-block').clone();
81 o
.data('edit-params', data
);
82 $('form', clone
).remove();
83 if (clone
.hasClass('contactCardLeft')) {
84 clone
.removeClass('contactCardLeft').addClass('contactCardRight');
86 else if (clone
.hasClass('contactCardRight')) {
87 clone
.removeClass('contactCardRight').addClass('contactCardLeft');
89 var cl
= $('.crm-inline-edit', clone
);
90 var clData
= cl
.data('edit-params');
91 var locNo
= clData
.locno
++;
92 cl
.attr('id', cl
.attr('id').replace(locNo
, clData
.locno
)).removeClass('form');
93 o
.closest('.crm-summary-block').after(clone
);
94 dependent
= dependent
.add($('.crm-inline-edit', clone
));
96 $('a.ui-notify-close', '#crm-notification-container').click();
98 if (o
.hasClass('address') && !o
.hasClass('add-new') && !response
.addressId
) {
100 CRM
.status(ts('Address Deleted'));
103 // Reload this block plus all dependent blocks
104 reloadBlock(dependent
.add(o
));
105 CRM
.status(ts('Saved'));
109 // Handle formRule error
110 $('.crm-container-snippet', o
).replaceWith(response
.content
);
111 $('form', o
).validate(CRM
.validate
.params
);
112 $('form', o
).ajaxForm(ajaxFormParams
);
113 o
.trigger('crmFormError', [response
]).trigger('crmFormLoad').trigger('crmLoad');
118 * Configure optimistic locking mechanism for inplace editing
120 * options.ignoreLabel: string, text for a button
121 * options.reloadLabel: string, text for a button
123 $.fn
.crmFormContactLock = function(options
) {
125 // AFTER ERROR: Render any "Ignore" and "Restart" buttons
126 return this.on('crmFormError', function(event
, obj
, status
) {
127 var o
= $(event
.target
);
128 var data
= o
.data('edit-params');
129 var errorTag
= o
.find('.update_oplock_ts');
130 if (errorTag
.length
> 0) {
132 .addClass('crm-lock-button css_right')
135 var buttonContainer
= o
.find('.crm-lock-button');
137 .addClass('crm-button')
138 .text(options
.saveAnywayLabel
)
140 $(form
).find('input[name=oplock_ts]').val(errorTag
.attr('data:update_oplock_ts'));
141 errorTag
.parent().hide();
142 $(this).closest('form').find('.crm-form-submit.default').first().click();
145 .appendTo(buttonContainer
)
148 .addClass('crm-button')
149 .text(options
.reloadLabel
)
151 window
.location
.reload();
154 .appendTo(buttonContainer
)
160 function errorHandler(response
) {
161 CRM
.alert(ts('Unable to reach the server. Please refresh this page in your browser and try again.'), ts('Network Error'), 'error');
162 $('.crm-inline-edit.form form').unblock();
166 // don't perform inline edit during print mode
167 if (CRM
.summaryPrint
.mode
) {
168 $('div').removeClass('crm-inline-edit');
169 $('.crm-inline-block-content > div.crm-edit-help').remove();
170 $('div.crm-inline-block-content').removeAttr('title');
173 var oldName
= 'CiviCRM';
174 var nameTitle
= $('#crm-remove-title');
175 if (nameTitle
.length
> 0) {
176 oldName
= nameTitle
.text();
177 nameTitle
.parent('h1').remove();
180 $('h1').each(function() {
181 if ($(this).text() == oldName
) {
186 function refreshTitle() {
187 var contactName
= $('.crm-summary-display_name').text();
188 contactName
= $.trim(contactName
);
189 document
.title
= $('title').html().replace(oldName
, contactName
);
190 oldName
= contactName
;
192 $('#contactname-block').load(refreshTitle
);
196 $('.crm-inline-edit-container')
197 .addClass('crm-edit-ready')
198 // Allow links inside edit blocks to be clicked without triggering edit
199 .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
) {
200 if (event
.which
== 1) {
201 event
.stopPropagation();
205 // Respond to a click (not drag, not right-click) of crm-inline-edit blocks
206 .on('mousedown', '.crm-inline-edit:not(.form)', function(button
) {
207 if (button
.which
== 1) {
209 setTimeout(function() {clicking
= null;}, 500);
212 .on('mouseup', '.crm-inline-edit:not(.form)', function(button
) {
213 if (clicking
=== this && button
.which
== 1) {
214 crmFormInline($(this));
217 // Inline edit form cancel button
218 .on('click', '.crm-inline-edit :submit[name$=cancel]', function() {
219 var container
= $(this).closest('.crm-inline-edit.form');
220 $('form', container
).ajaxFormUnbind();
221 $('.inline-edit-hidden-content', container
).nextAll().remove();
222 $('.inline-edit-hidden-content > *:first-child', container
).unwrap();
223 container
.removeClass('form');
224 $('.crm-inline-edit-container').addClass('crm-edit-ready');
225 $('a.ui-notify-close', '#crm-notification-container').click();
228 // Switch tabs when clicking tag link
229 .on('click', '#tagLink a', function() {
230 $('#tab_tag a').click();
233 // make sure only one is_primary radio is checked
234 .on('change', '[class$=is_primary] input', function() {
235 if ($(this).is(':checked')) {
236 $('[class$=is_primary] input', $(this).closest('form')).not(this).prop('checked', false);
239 // make sure only one builk_mail radio is checked
240 .on('change', '.crm-email-bulkmail input', function(){
241 if ($(this).is(':checked')) {
242 $('.crm-email-bulkmail input').not(this).prop('checked', false);
245 // handle delete link within blocks
246 .on('click', '.crm-delete-inline', function(e
) {
247 var row
= $(this).closest('tr');
248 var form
= $(this).closest('form');
250 $('input', row
).val('');
251 //if the primary is checked for deleted block
252 //unset and set first as primary
253 if ($('[class$=is_primary] input:checked', row
).length
> 0) {
254 $('[class$=is_primary] input', row
).prop('checked', false);
255 $('[class$=is_primary] input:first', form
).prop('checked', true );
257 $('.add-more-inline', form
).show();
261 .on('click', '.crm-inline-edit.address .delete-button', function(e
) {
262 var $block
= $(this).closest('.crm-inline-edit.address');
263 CRM
.confirm({message
: ts('Are you sure you want to delete this address?')})
264 .on('crmConfirm:yes', function() {
265 CRM
.api3('address', 'delete', {id
: $block
.data('edit-params').aid
}, true)
266 .done(function(data
) {
267 $('.crm-inline-edit-container').addClass('crm-edit-ready');
269 reloadBlock('.crm-inline-edit.address:not(.add-new)');
274 // add more and set focus to new row
275 .on('click', '.add-more-inline', function(e
) {
276 var form
= $(this).closest('form');
277 var row
= $('tr[class="hiddenElement"]:first', form
);
278 row
.removeClass('hiddenElement');
279 $('input:focus', form
).blur();
280 $('input:first', row
).focus();
281 if ($('tr[class="hiddenElement"]').length
< 1) {
286 // Trigger cancel button on esc keypress
287 $(document
).keydown(function(key
) {
288 if (key
.which
== 27) {
289 $('.crm-inline-edit.form :submit[name$=cancel]').click();
293 // Switch tabs when clicking log link
294 .on('click', '#crm-record-log a.crm-log-view', function() {
295 $('#tab_log a').click();
298 // Handle action links in popup
299 .on('click', '.crm-contact_actions-list a, .crm-contact_activities-list a', function(e
) {
300 $('#crm-contact-actions-list').hide();
301 if ($(this).attr('href') === '#') {
302 var $tab
= $('#tab_' + ($(this).data('tab') || 'summary'));
303 CRM
.tabHeader
.focus($tab
);
306 CRM
.popup
.call(this, e
);
309 .on('crmPopupFormSuccess', '.crm-contact_actions-list a, .crm-contact_activities-list a', function() {
310 var $tab
= $('#tab_' + ($(this).data('tab') || 'summary'));
311 CRM
.tabHeader
.resetTab($tab
);
312 CRM
.tabHeader
.focus($tab
);
316 .on('click', function(e
) {
317 if ($(e
.target
).is('#crm-contact-actions-link, #crm-contact-actions-link *')) {
318 $('#crm-contact-actions-list').show();
321 $('#crm-contact-actions-list').hide();
323 .on('crmFormSuccess crmLoad', function(e
, data
) {
324 // Update changelog tab and contact footer
325 if (data
&& data
.changeLog
) {
326 if (data
.changeLog
.count
) {
327 CRM
.tabHeader
.updateCount('#tab_log', data
.changeLog
.count
);
329 if (data
.changeLog
.markup
) {
330 $("#crm-record-log").replaceWith(data
.changeLog
.markup
);
334 .on('crmFormSuccess', function(e
, data
) {
335 // Advanced logging... just increment the changelog tab count to avoid the overhead of reloading the data
336 if (CRM
.incrementChangeLogTab
) {
337 CRM
.incrementChangeLogTab();
339 // Refresh changelog tab next time it is opened
340 CRM
.tabHeader
.resetTab('#tab_log');
341 // Refresh dependent blocks
342 if (data
&& data
.reloadBlocks
) {
343 reloadBlock(data
.reloadBlocks
.join(','));
348 * Make contact summary fit in small screens
350 function onResize() {
351 var contactwidth
= $('#crm-container #mainTabContainer').width();
352 if (contactwidth
< 600) {
353 $('#crm-container #mainTabContainer').addClass('narrowpage');
354 $('#crm-container #mainTabContainer.narrowpage #contactTopBar td').each(function (index
) {
356 if (index
% 2 === 0) {
357 $(this).parent().after('<tr class="narrowadded"></tr>');
360 $(this).parent().next().append(item
);
365 $('#crm-container #mainTabContainer.narrowpage').removeClass('narrowpage');
366 $('#crm-container #mainTabContainer #contactTopBar tr.narrowadded td').each(function () {
368 var parent
= $(this).parent();
369 $(this).parent().prev().append(nitem
);
370 if (parent
.children().size() === 0) {
374 $('#crm-container #mainTabContainer.narrowpage #contactTopBar tr.added').detach();
376 var cformwidth
= $('#crm-container #Contact .contact_basic_information-section').width();
378 if (cformwidth
< 720) {
379 $('#crm-container .contact_basic_information-section').addClass('narrowform');
380 $('#crm-container .contact_basic_information-section table.form-layout-compressed td .helpicon').parent().addClass('hashelpicon');
381 if (cformwidth
< 480) {
382 $('#crm-container .contact_basic_information-section').addClass('xnarrowform');
385 $('#crm-container .contact_basic_information-section.xnarrowform').removeClass('xnarrowform');
389 $('#crm-container .contact_basic_information-section.narrowform').removeClass('narrowform');
390 $('#crm-container .contact_basic_information-section.xnarrowform').removeClass('xnarrowform');
395 $(window
).resize(onResize
);