CRM-14015 - Abstract entity/field extraction from crmEditable
authorColeman Watts <coleman@civicrm.org>
Sun, 22 Dec 2013 06:01:02 +0000 (22:01 -0800)
committerColeman Watts <coleman@civicrm.org>
Mon, 6 Jan 2014 19:10:40 +0000 (11:10 -0800)
js/jquery/jquery.crmeditable.js
templates/CRM/common/enableDisableApi.tpl

index e0c620dd929acf988317b6a76fb7b3164e297d24..539ef4e73aff9ca3d63ef548528a9145c37c92f1 100644 (file)
 
 (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) {
-          console && console.log && console.log("Couldn't get the entity id. You need to set class='crm-entity' on a parent element of the field");
-          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) {
-          console && console.log && console.log("FATAL crm-editable: Couldn't get the entity id. You need to set class='crm-entity' id='{entityName}-{id}'");
-          return false;
-        }
-        var e=domid.match(/(\S*)-(\S*)/);
-        if (!e) {
-           console && console.log && console.log("Couldn't get the entity id. You need to set class='crm-entity' id='{entityName}-{id}'");
-           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) {
-        var fieldName = $(field).data('field') || field.className.match(/crmf-(\S*)/)[1];
-        if (!fieldName) {
-          console && console.log && console.log("Couldn't get the crm-editable field name to modify. You need to set crmf-{field_name} or data-{field_name}");
+  $.fn.crmEditableEntity = function() {
+    var
+      el = this[0],
+      ret = {},
+      $row = this.first().closest('.crm-entity');
+    ret.entity = $row.data('entity');
+    ret.id = $row.data('id');
+    if (!ret.entity || !ret.id) {
+      ret.entity = $row[0].id.split('-')[0];
+      ret.id = $row[0].id.split('-')[1];
+    }
+    if (!ret.entity || !ret.id) {
+      return false;
+    }
+    $('.crm-editable', $row).each(function() {
+      var fieldName = $(this).data('field') || this.className.match(/crmf-(\S*)/)[1];
+      if (fieldName) {
+        ret[fieldName] = $(this).text();
+        if (this === el) {
+          ret.field = fieldName;
         }
-        return fieldName;
       }
+    });
+    return ret;
+  };
 
+    $.fn.crmEditable = function (options) {
       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'])
+          var info = $(this).crmEditableEntity();
+          if (!info.field) {
             return false;
-          params['value']=checked?'1':'0';//seems that the ajax backend gets lost with boolean
-
-          CRM.api(entity,'setvalue',params,{
+          }
+          var checked = $(this).is(':checked');
+          var params = {
+            sequential: 1,
+            id: info.id,
+            field: info.field,
+            value: checked ? 1 : 0
+          };
+          CRM.api(info.entity, 'setvalue', params, {
             context: this,
             error: function (data) {
-              editableSettings.error.call(this,entity,params.field,checked,data);
+              editableSettings.error.call(this, info.entity, info.field, checked, data);
             },
             success: function (data) {
-              editableSettings.success.call(this,entity,params.field,checked,data);
+              editableSettings.success.call(this, info.entity, info.field, checked, data);
             }
           });
         });
         }
 
         $i.editable(function(value,settings) {
-        //$i.editable(function(value,editableSettings) {
-          parent=$i.closest('.crm-entity');
-          if (!parent) {
-            console && console.log && console.log("crm-editable: you need to define one parent element that has a class .crm-entity");
-            return;
-          }
-
           $i.addClass ('crm-editable-saving');
-          var params = {};
-          var entity = null;
-          params['field']=getFieldName(this);
-          if (!params['field'])
+          var
+            info = $i.crmEditableEntity(),
+            params= {},
+            action = $i.data('action') || 'setvalue';
+          if (!info.field) {
             return false;
-          params['value']=value;
-          if  (!getEntityID (this,function (e,id) {
-            entity=e;
-            params.id = id;
-          })) {return;}
-
-          if (params.id == "new") {
-            params.id = '';
           }
-
-          if ($i.data('action')) {
-            var fieldName = params['field'];
-            delete params['field'];
-            delete params['value'];
-
-            params[fieldName]=value;//format for create at least
-            action=$i.data('action');
-          } else {
-            action="setvalue";
+          if (info.id && info.id !== 'new') {
+            params.id = info.id;
+          }
+          if (action === 'setvalue') {
+            params.field = info.field;
+            params.value = value;
+          }
+          else {
+            params[info.field] = value;
           }
-          CRM.api(entity, action, params, {
+          CRM.api(info.entity, action, params, {
               context: this,
               error: function (data) {
-                editableSettings.error.call(this,entity,fieldName,value,data);
+                editableSettings.error.call(this, info.entity, info.field, value, data);
               },
               success: function (data) {
                 if ($i.data('options')){
                   value = $i.data('options')[value];
                 }
-                editableSettings.success.call(this,entity,fieldName,value,data);
+                editableSettings.success.call(this, info.entity, info.field, value, data);
               }
             });
            },settings);
index 649bf8fd9a2343afe6f145ade02ae2e140f28f0a..63e355d523a7cabae376d879b4e1083437e76c9b 100644 (file)
@@ -27,7 +27,7 @@
 {literal}
 <script type="text/javascript">
   cj(function($) {
-    var $row, $table, entity, id, enabled, fieldLabel;
+    var $row, $table, info, enabled, fieldLabel;
 
     function refresh() {
       if (false && $.fn.DataTable.fnIsDataTable($table[0])) { // fixme why doesn't this work?
         // Refresh an existing ajax container or create a new one
         $row.closest('.crm-ajax-container, #crm-main-content-wrapper').crmSnippet().crmSnippet('refresh');
       }
-      var msg = enabled ? {/literal}'{ts escape="js" 1="<em>%1</em>"}%1 Disabled{/ts}' : '{ts escape="js" 1="<em>%1</em>"}%1 Enabled{/ts}'{literal};
-      CRM.alert('', ts(msg, fieldLabel), 'success');
+      {/literal} {* client-side variable substitutions in smarty are AWKWARD! *}
+      var msg = enabled ? '{ts escape="js" 1="<em>%1</em>"}%1 Disabled{/ts}' : '{ts escape="js" 1="<em>%1</em>"}%1 Enabled{/ts}'{literal};
+      CRM.alert('', ts(msg, {1: fieldLabel}), 'success');
     }
 
     function save() {
       $table = $row.closest('table');
       $table.block();
-      CRM.api(entity, 'setvalue', {id: id, field: 'is_active', value: enabled ? 0 : 1}, {success: refresh});
+      CRM.api(info.entity, 'setvalue', {id: info.id, field: 'is_active', value: enabled ? 0 : 1}, {success: refresh});
       if (enabled) {
         $(this).dialog('close');
       }
@@ -51,7 +52,7 @@
 
     function confirmation() {
       var conf = $(this);
-      $.getJSON(CRM.url('civicrm/ajax/statusmsg', {entity: entity, id: id}), function(response) {
+      $.getJSON(CRM.url('civicrm/ajax/statusmsg', {entity: info.entity, id: info.id}), function(response) {
         conf.html(response.content);
         if (!response.illegal) {
           conf.dialog('option', 'buttons', [
       });
     }
 
-    function getLabel() {
-      var label = {/literal}'{ts escape="js"}Record{/ts}'{literal};
-      var labelField = $('.crmf-label, .crmf-title, [data-field=label], [data-field=title]', $row);
-      if (labelField.length) {
-        label = labelField.first().text();
-      }
-      // Format as object the way ts() wants it
-      fieldLabel = {1: label};
-    }
-
     function enableDisable() {
-      var $a = $(this);
-      $row = $a.closest('.crm-entity');
-      getLabel();
-      // FIXME: abstract and reuse code from $.crmEditable for fetching entity/id instead of reinventing it here
-      entity = $row.data('entity');
-      id = $row.data('id');
-      if (!entity || !id) {
-        entity = $row[0].id.split('-')[0];
-        id = $row[0].id.split('-')[1];
-      }
+      $row = $(this).closest('.crm-entity');
+      info = $(this).crmEditableEntity();
+      fieldLabel = info.label || info.title || info.name || {/literal}'{ts escape="js"}Record{/ts}'{literal};
       enabled = !$row.hasClass('disabled');
       if (enabled) {
         CRM.confirm({}, {{/literal}
-          {* client-side variable substitutions in smarty are AWKWARD! *}
-          title: ts('{ts escape="js" 1='%1'}Disable %1{/ts}', fieldLabel),
           message: '<div class="crm-loading-element">{ts escape="js"}Loading{/ts}...</div>',
+          {* client-side variable substitutions in smarty are AWKWARD! *}
+          title: ts('{ts escape="js" 1='%1'}Disable %1{/ts}{literal}', {1: fieldLabel}),
           width: 300,
           open: confirmation
-        {literal}});
+        });
       } else {
         save();
       }