// https://civicrm.org/licensing
-(function($) {
+(function($, _) {
+ "use strict";
+ /* jshint validthis: true */
+
// TODO: We'll need a way to clear this cache if options are edited.
// Maybe it should be stored in the CRM object so other parts of the app can use it.
// Note that if we do move it, we should also change the format of option lists to our standard sequential arrays
field: info.field,
value: $el.is(':checked') ? 1 : 0
};
- CRM.api3(info.entity, info.action, params, true)
- .fail(function(data) {
- editableSettings.error.call($el[0], info.entity, info.field, checked, data);
- })
- .done(function(data) {
- editableSettings.success.call($el[0], info.entity, info.field, checked, data);
- });
+ CRM.api3(info.entity, info.action, params, true);
});
}
- var defaults = {
- error: function(entity, field, value, data) {
- $(this).crmError(data.error_message, ts('Error'));
- $(this).removeClass('crm-editable-saving');
- },
- success: function(entity, field, value, data, settings) {
- var $i = $(this);
- if ($i.data('refresh')) {
- CRM.refreshParent($i);
- } else {
- $i.removeClass('crm-editable-saving crm-error crm-editable-editing');
- value = value === '' ? settings.placeholder : value;
- $i.html(value);
- }
- }
- };
-
- var editableSettings = $.extend({}, defaults, options);
return this.each(function() {
var $i,
- fieldName = "";
+ fieldName = "",
+ defaults = {
+ error: function(entity, field, value, data) {
+ restoreContainer();
+ $(this).html(originalValue || settings.placeholder).click();
+ var msg = $.isPlainObject(data) && data.error_message;
+ errorMsg = $(':input', this).first().crmError(msg || ts('Sorry an error occurred and your information was not saved'), ts('Error'));
+ },
+ success: function(entity, field, value, data, settings) {
+ restoreContainer();
+ if ($i.data('refresh')) {
+ CRM.refreshParent($i);
+ } else {
+ value = value === '' ? settings.placeholder : _.escape(value);
+ $i.html(value);
+ }
+ }
+ },
+ originalValue = '',
+ errorMsg,
+ editableSettings = $.extend({}, defaults, options);
if ($(this).hasClass('crm-editable-enabled')) {
return;
else {
params[info.field] = value;
}
- CRM.api3(info.entity, action, params, true)
+ CRM.api3(info.entity, action, params, {error: null})
.done(function(data) {
+ if (data.is_error) {
+ return editableSettings.error.call($el[0], info.entity, info.field, value, data);
+ }
if ($el.data('options')) {
value = $el.data('options')[value] || '';
}
// CRM-15759 - Workaround broken textarea handling in jeditable 1.7.1
$i.click(function() {
$('textarea', this).off()
- .on('blur', function() {
- $i.find('button[type=cancel]').click();
+ // Fix cancel-on-blur
+ .on('blur', function(e) {
+ if (!e.relatedTarget || !$(e.relatedTarget).is('.crm-editable-form button')) {
+ $i.find('button[type=cancel]').click();
+ }
})
+ // Add support for ctrl-enter shortcut key
.on('keydown', function (e) {
if (e.ctrlKey && e.keyCode == 13) {
- // Ctrl-Enter pressed
$i.find('button[type=submit]').click();
e.preventDefault();
}
// FIXME: This should be a response to an event instead of coupled with this function but jeditable 1.7.1 doesn't trigger any events :(
$i.addClass('crm-editable-editing');
+ originalValue = value;
+
if ($i.data('type') == 'select' || $i.data('type') == 'boolean') {
if ($i.data('options')) {
return formatOptions($i.data('options'));
});
}
return formatOptions(optionsCache[hash]);
-
}
- return value.replace(/<(?:.|\n)*?>/gm, '');
+ // Unwrap contents then replace html special characters with plain text
+ return _.unescape(value.replace(/<(?:.|\n)*?>/gm, ''));
}
function formatOptions(options) {
}
function restoreContainer() {
- $i.removeClass('crm-editable-editing');
+ if (errorMsg && errorMsg.close) errorMsg.close();
+ $i.removeClass('crm-editable-saving crm-editable-editing');
}
});
};
-})(jQuery);
+ $(document).on('crmLoad', function(e) {
+ $('.crm-editable', e.target).not('thead *').crmEditable();
+ });
+
+})(jQuery, CRM._);