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