/* +--------------------------------------------------------------------+ | CiviCRM version 4.2 | +--------------------------------------------------------------------+ | This file is a part of CiviCRM. | | | | CiviCRM is free software; you can copy, modify, and distribute it | | under the terms of the GNU Affero General Public License | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | | | | CiviCRM is distributed in the hope that it will be useful, but | | WITHOUT ANY WARRANTY; without even the implied warranty of | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | | See the GNU Affero General Public License for more details. | | | | You should have received a copy of the GNU Affero General Public | | License and the CiviCRM Licensing Exception along | | with this program; if not, contact CiviCRM LLC | | at info[AT]civicrm[DOT]org. If you have questions about the | | GNU Affero General Public License or the licensing of CiviCRM, | | see the CiviCRM license FAQ at http://civicrm.org/licensing | +--------------------------------------------------------------------+ * * Copyright (C) 2012 Xavier Dutoit * Licensed to CiviCRM under the Academic Free License version 3.0. * * * This offers two features: * - crmEditable() edit in place of a single field * (mostly a wrapper that binds jeditable features with the ajax api and replies on crm-entity crmf-{field} html conventions) * if you want to add an edit in place on a template: * - add a class crm-entity and id {EntityName}-{Entityid} higher in the dom * - add a class crm-editable and crmf-{FieldName} around the field (you can add a span if needed) * - add data-action=create if you need to specify the api action to call (default setvalue) * crmf- stands for crm field * - crmForm() * this embed a civicrm form and make it in place (load+ajaxForm) * to make it easier to customize the form (eg. hide a button...) it triggers a 'load' event on the form. you can then catch the load on your code (using the $('#id_of_the_form').on(function(){//do something */ (function($){ $.fn.crmEditable = function (options) { // for a jquery object (the crm-editable), find the entity name and id to apply the changes to // call result function(entity,id). The caller is responsible to use these params and do the needed var getEntityID = function (field,result) { var domid= $(field).closest('.crm-entity'); if (!domid) { $().crmNotification ("Couldn't get the entity id. You need to set class='crm-entity' on a parent element of the field",'notification',domid); return false; } // trying to extract using the html5 data if (domid.data('entity')) { result (domid.data('entity'),domid.data('id')); return true; } domid=domid.attr('id'); if (!domid) { $().crmNotification ("FATAL crm-editable: Couldn't get the entity id. You need to set class='crm-entity' id='{entityName}-{id}'",'notification',domid); return false; } var e=domid.match(/(\S*)-(\S*)/); if (!e) { $().crmNotification ("Couldn't get the entity id. You need to set class='crm-entity' id='{entityName}-{id}'",'notification',this); return false; } result(e[1],e[2]); return true; } // param in : a dom object that contains the field name as a class crmf-xxx var getFieldName = function (field) { if ($(field).data('field')) { return $(field).data('field'); } var fieldName=field.className.match(/crmf-(\S*)/)[1]; if (!fieldName) { $().crmNotification ("Couldn't get the crm-editable field name to modify. You need to set crmf-{field_name} or data-{field_name}",'notification',field); return false; } return fieldName; } var checkable = function () { $(this).change (function() { var params={sequential:1}; var entity = null; var checked = $(this).is(':checked'); if (!getEntityID (this,function (e,id) { entity=e; params.id = id; })) { return }; params['field']=getFieldName(this); if (!params['field']) return false; params['value']=checked?'1':'0';//seems that the ajax backend gets lost with boolean //$().crmAPI.call(this,entity,'create',params,{ create is still too buggy & perf $().crmAPI.call(this,entity,'setvalue',params,{ error: function (data) { editableSettings.error.call(this,entity,fieldName,checked,data); }, success: function (data) { editableSettings.success.call(this,entity,fieldName,checked,data); } }); }); }; var defaults = { form:{}, callBack:function(data){ if (data.is_error) { editableSettings.error.call (this,data); } else { return editableSettings.success.call (this,data); } }, error: function(entity,field,value,data) { $().crmNotification (data.error_message,'error',data); $(this).removeClass ('crm-editable-saving').addClass('crm-editable-error'); }, success: function(entity,field,value,data) { var $i=$(this); $().crmNotification (false); $i.removeClass ('crm-editable-saving').removeClass ('crm-editable-error'); $i.html(value); } } var editableSettings = $.extend({}, defaults, options); return this.each(function() { var $i = $(this); var fieldName = ""; if (this.nodeName == "INPUT" && this.type=="checkbox") { checkable.call(this,this); return; } if (this.nodeName = 'A') { if (this.className.indexOf('crmf-') == -1) { // it isn't a jeditable field var formSettings= $.extend({}, editableSettings.form , {source: $i.attr('href') ,success: function (result) { if ($i.hasClass('crm-dialog')) { $('.ui-dialog').dialog('close').remove(); } else $i.next().slideUp().remove(); $i.trigger('success',result); } }); var id= $i.closest('.crm-entity').attr('id'); if (id) { var e=id.match(/(\S*)-(\S*)/); if (!e) $().crmNotification ("Couldn't get the entity id. You need to set class='crm-entity' id='{entityName}-{id}'",'notification',this); formSettings.entity=e[1]; formSettings.id=e[2]; } if ($i.hasClass('crm-dialog')) { $i.click (function () { var $n=$('