CRM-16310 - implement pagination on custom field option list page
authorjitendrapurohit <jitendra.purohit@webaccessglobal.com>
Wed, 27 May 2015 07:16:00 +0000 (12:46 +0530)
committerjitendrapurohit <jitendra.purohit@webaccessglobal.com>
Fri, 12 Jun 2015 12:40:31 +0000 (18:10 +0530)
CRM/Core/BAO/CustomOption.php
CRM/Core/xml/Menu/Custom.xml
CRM/Custom/Page/AJAX.php [new file with mode: 0644]
CRM/Custom/Page/Option.php
templates/CRM/Custom/Page/Option.tpl

index 88c06b122e001f484796573e3545241a28406e4c..00a2f9c0cf9551c1b521d4f8861bb5dbeafe2686 100644 (file)
@@ -105,6 +105,127 @@ class CRM_Core_BAO_CustomOption {
     return $options;
   }
 
+  /**
+   * wrapper for ajax option selector.
+   *
+   * @param array $params
+   *   Associated array for params record id.
+   *
+   * @return array
+   *   associated array of option list
+   *   -rp = rowcount
+   *   -page= offset
+   */
+  static public function getOptionListSelector(&$params) {
+
+    $options = array();
+
+    //get the default value from custom fields
+    $customFieldBAO = new CRM_Core_BAO_CustomField();
+    $customFieldBAO->id = $params['fid'];
+    if ($customFieldBAO->find(TRUE)) {
+      $defaultValue = $customFieldBAO->default_value;
+      $fieldHtmlType = $customFieldBAO->html_type;
+    }
+    else {
+      CRM_Core_Error::fatal();
+    }
+    $defVal = explode(CRM_Core_DAO::VALUE_SEPARATOR,
+      substr($defaultValue, 1, -1)
+    );
+
+    // format the params
+    $params['offset'] = ($params['page'] - 1) * $params['rp'];
+    $params['rowCount'] = $params['rp'];
+    $params['sort'] = CRM_Utils_Array::value('sortBy', $params);
+
+    $field = CRM_Core_BAO_CustomField::getFieldObject($params['fid']);
+
+    // get the option group id
+    $optionGroupID = $field->option_group_id;
+    if (!$optionGroupID) {
+      return $options;
+    }
+    $queryParams = array(1 => array($optionGroupID, 'Integer'));
+    $total = "SELECT COUNT(*) FROM civicrm_option_value WHERE option_group_id = %1";
+    $params['total'] = CRM_Core_DAO::singleValueQuery($total, $queryParams);
+
+    $limit = " LIMIT {$params['offset']}, {$params['rowCount']} ";
+
+    $orderBy = ' ORDER BY options.weight asc';
+    if (!empty($params['sort'])) {
+      $orderBy = ' ORDER BY ' . CRM_Utils_Type::escape($params['sort'], 'String');
+    }
+
+    $query = "SELECT * FROM civicrm_option_value as options WHERE option_group_id = %1 {$orderBy} {$limit}";
+    $dao = CRM_Core_DAO::executeQuery($query, $queryParams);
+    $links = CRM_Custom_Page_Option::actionLinks();
+
+    $fields = array('id', 'label', 'value', 'weight');
+    $config = CRM_Core_Config::singleton();
+    while ($dao->fetch()) {
+      $options[$dao->id] = array();
+      foreach ($fields as $k) {
+        $options[$dao->id][$k] = $dao->$k;
+      }
+      $action = array_sum(array_keys($links));
+      $class = 'crm-entity';
+      // update enable/disable links depending on custom_field properties.
+      if ($dao->is_active) {
+        $action -= CRM_Core_Action::ENABLE;
+      }
+      else {
+        $class .= ' disabled';
+        $action -= CRM_Core_Action::DISABLE;
+      }
+      if ($fieldHtmlType == 'CheckBox' ||
+        $fieldHtmlType == 'AdvMulti-Select' ||
+        $fieldHtmlType == 'Multi-Select'
+      ) {
+        if (in_array($dao->value, $defVal)) {
+          $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
+        }
+        else {
+          $options[$dao->id]['is_default'] = '';
+        }
+      }
+      else {
+        if ($defaultValue == $dao->value) {
+          $options[$dao->id]['is_default'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
+        }
+        else {
+          $options[$dao->id]['is_default'] = '';
+        }
+      }
+
+      $options[$dao->id]['class'] = $dao->id . ',' . $class;
+      $options[$dao->id]['is_active'] = !empty($dao->is_active) ? 'Yes' : 'No';
+      $options[$dao->id]['links'] = CRM_Core_Action::formLink($links,
+          $action,
+          array(
+            'id' => $dao->id,
+            'fid' => $params['fid'],
+            'gid' => $params['gid'],
+          ),
+          ts('more'),
+          FALSE,
+          'customOption.row.actions',
+          'customOption',
+          $dao->id
+        );
+    }
+    // Add order changing widget to selector
+    $returnURL = CRM_Utils_System::url('civicrm/admin/custom/group/field/option',
+      "reset=1&action=browse&gid={$params['gid']}&fid={$params['fid']}"
+    );
+    $filter = "option_group_id = {$optionGroupID}";
+    CRM_Utils_Weight::addOrder($options, 'CRM_Core_DAO_OptionValue',
+      'id', $returnURL, $filter
+    );
+
+    return $options;
+  }
+
   /**
    * Returns the option label for a custom field with a specific value. Handles all
    * custom field data and html types
index 2ddc99d926ce65bfeeb50ee866936f56acaac594..b58c6bcfb5041c238639ac7931caa0246da58b79 100644 (file)
@@ -5,4 +5,9 @@
      <path>civicrm/custom/add</path>
      <page_callback>CRM_Custom_Form_CustomData</page_callback>
   </item>
-</menu>
\ No newline at end of file
+  <item>
+     <path>civicrm/ajax/optionlist</path>
+     <page_callback>CRM_Custom_Page_AJAX::getOptionList</page_callback>
+     <access_arguments>access CiviCRM</access_arguments>
+  </item>
+</menu>
diff --git a/CRM/Custom/Page/AJAX.php b/CRM/Custom/Page/AJAX.php
new file mode 100644 (file)
index 0000000..fac96f9
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+/*
+ +--------------------------------------------------------------------+
+ | CiviCRM version 4.6                                                |
+ +--------------------------------------------------------------------+
+ | Copyright CiviCRM LLC (c) 2004-2015                                |
+ +--------------------------------------------------------------------+
+ | 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        |
+ +--------------------------------------------------------------------+
+ */
+
+/**
+ *
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2015
+ *
+ */
+
+/**
+ * This class contains the functions that are called using AJAX (jQuery)
+ */
+class CRM_Custom_Page_AJAX {
+  /**
+   * Get list of options.
+   *
+   */
+  public static function getOptionList() {
+    $params = $_REQUEST;
+
+    $sortMapper = array(
+      0 => 'options.label',
+      1 => 'options.value',
+      2 => '',
+      3 => 'options.weight',
+      4 => '',
+      5 => '',
+    );
+
+    $sEcho = CRM_Utils_Type::escape($_REQUEST['sEcho'], 'Integer');
+    $offset = isset($_REQUEST['iDisplayStart']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayStart'], 'Integer') : 0;
+    $rowCount = isset($_REQUEST['iDisplayLength']) ? CRM_Utils_Type::escape($_REQUEST['iDisplayLength'], 'Integer') : 25;
+    $sort = isset($_REQUEST['iSortCol_0']) ? CRM_Utils_Array::value(CRM_Utils_Type::escape($_REQUEST['iSortCol_0'], 'Integer'), $sortMapper) : NULL;
+    $sortOrder = isset($_REQUEST['sSortDir_0']) ? CRM_Utils_Type::escape($_REQUEST['sSortDir_0'], 'String') : 'asc';
+
+    if ($sort && $sortOrder) {
+      $params['sortBy'] = $sort . ' ' . $sortOrder;
+    }
+
+    $params['page'] = ($offset / $rowCount) + 1;
+    $params['rp'] = $rowCount;
+
+    $options = CRM_Core_BAO_CustomOption::getOptionListSelector($params);
+
+    $iFilteredTotal = $iTotal = $params['total'];
+    $selectorElements = array(
+      'label',
+      'value',
+      'is_default',
+      'weight',
+      'is_active',
+      'links',
+      'class',
+    );
+
+    header('Content-Type: application/json');
+    echo CRM_Utils_JSON::encodeDataTableSelector($options, $sEcho, $iTotal, $iFilteredTotal, $selectorElements);
+    CRM_Utils_System::civiExit();
+  }
+
+}
index 47e0fa8c3c506d8750a92d76370d816ff5cd9fdd..fb73094c7afafb04b27e0508f8be7ef5efd385b2 100644 (file)
@@ -114,19 +114,6 @@ class CRM_Custom_Page_Option extends CRM_Core_Page {
    * @return void
    */
   public function browse() {
-    //get the default value from custom fields
-    $customFieldBAO = new CRM_Core_BAO_CustomField();
-    $customFieldBAO->id = $this->_fid;
-    if ($customFieldBAO->find(TRUE)) {
-      $defaultValue = $customFieldBAO->default_value;
-      $fieldHtmlType = $customFieldBAO->html_type;
-    }
-    else {
-      CRM_Core_Error::fatal();
-    }
-    $defVal = explode(CRM_Core_DAO::VALUE_SEPARATOR,
-      substr($defaultValue, 1, -1)
-    );
 
     // get the option group id
     $optionGroupID = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_CustomField',
@@ -155,79 +142,6 @@ WHERE  option_group_id = %1";
       CRM_Utils_System::setTitle($newTitle);
       $this->assign('reusedNames', $reusedNames);
     }
-
-    $query = "
-SELECT   *
-  FROM   civicrm_option_value
- WHERE   option_group_id = %1
-ORDER BY weight, label
-";
-    $params = array(1 => array($optionGroupID, 'Integer'));
-    $dao = CRM_Core_DAO::executeQuery($query, $params);
-
-    $customOption = array();
-    $fields = array('label', 'value', 'is_active', 'weight');
-    $config = CRM_Core_Config::singleton();
-    while ($dao->fetch()) {
-      $customOption[$dao->id] = array();
-      foreach ($fields as $field) {
-        $customOption[$dao->id][$field] = $dao->$field;
-      }
-
-      $action = array_sum(array_keys($this->actionLinks()));
-
-      // update enable/disable links depending on custom_field properties.
-      if ($dao->is_active) {
-        $action -= CRM_Core_Action::ENABLE;
-      }
-      else {
-        $action -= CRM_Core_Action::DISABLE;
-      }
-
-      if ($fieldHtmlType == 'CheckBox' ||
-        $fieldHtmlType == 'AdvMulti-Select' ||
-        $fieldHtmlType == 'Multi-Select'
-      ) {
-        if (in_array($dao->value, $defVal)) {
-          $customOption[$dao->id]['default_value'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
-        }
-        else {
-          $customOption[$dao->id]['default_value'] = '';
-        }
-      }
-      else {
-        if ($defaultValue == $dao->value) {
-          $customOption[$dao->id]['default_value'] = '<img src="' . $config->resourceBase . 'i/check.gif" />';
-        }
-        else {
-          $customOption[$dao->id]['default_value'] = '';
-        }
-      }
-
-      $customOption[$dao->id]['action'] = CRM_Core_Action::formLink(self::actionLinks(),
-        $action,
-        array(
-          'id' => $dao->id,
-          'fid' => $this->_fid,
-          'gid' => $this->_gid,
-        ),
-        ts('more'),
-        FALSE,
-        'customOption.row.actions',
-        'customOption',
-        $dao->id
-      );
-    }
-
-    // Add order changing widget to selector
-    $returnURL = CRM_Utils_System::url('civicrm/admin/custom/group/field/option',
-      "reset=1&action=browse&gid={$this->_gid}&fid={$this->_fid}"
-    );
-    $filter = "option_group_id = {$optionGroupID}";
-    CRM_Utils_Weight::addOrder($customOption, 'CRM_Core_DAO_OptionValue',
-      'id', $returnURL, $filter
-    );
-    $this->assign('customOption', $customOption);
   }
 
   /**
index f02fd8a3deab789bf024096ac1d4cbd65c9ba424..79694dffb05daf989984507bd8ff2a6b56df7b83 100644 (file)
 {if $action eq 1 or $action eq 2 or $action eq 4 or $action eq 8}
     {include file="CRM/Custom/Form/Option.tpl"}
 {else}
-  {if $customOption}
-    {if $reusedNames}
-        <div class="message status">
-            <div class="icon inform-icon"></div> &nbsp; {ts 1=$reusedNames}These Multiple Choice Options are shared by the following custom fields: %1{/ts}
-        </div>
-    {/if}
+  {if $reusedNames}
+      <div class="message status">
+        <div class="icon inform-icon"></div> &nbsp; {ts 1=$reusedNames}These Multiple Choice Options are shared by the following custom fields: %1{/ts}
+      </div>
+  {/if}
 
-    <div id="field_page">
-      <p></p>
-      <div class="form-item">
-        {strip}
-        {* handle enable/disable actions*}
-         {include file="CRM/common/enableDisableApi.tpl"}
-        <table class="selector row-highlight">
+  <div id="field_page">
+    <p></p>
+    <div class="form-item">
+      {* handle enable/disable actions*}
+      {include file="CRM/common/enableDisableApi.tpl"}
+      <table class="crm-option-selector">
+      <thead>
           <tr class="columnheader">
-            <th>{ts}Label{/ts}</th>
-            <th>{ts}Value{/ts}</th>
-            <th>{ts}Default{/ts}</th>
-            <th>{ts}Order{/ts}</th>
-            <th>{ts}Enabled?{/ts}</th>
-            <th>&nbsp;</th>
+            <th class='crm-custom_option-label'>{ts}Label{/ts}</th>
+            <th class='crm-custom_option-value'>{ts}Value{/ts}</th>
+            <th class='crm-custom_option-default_value'>{ts}Default{/ts}</th>
+            <th class='nowrap crm-custom_option-weight'>{ts}Order{/ts}</th>
+            <th class='crm-custom_option-is_active  nosort'>{ts}Enabled?{/ts}</th>
+            <th class='crm-custom_option-links'>&nbsp;</th>
+            <th class='hiddenElement'>&nbsp;</th>
           </tr>
-          {foreach from=$customOption item=row key=id}
-            <tr id="OptionValue-{$id}" class="crm-entity {cycle values="odd-row,even-row"} {$row.class} crm-custom_option{if !$row.is_active} disabled{/if}">
-              <td class="crm-custom_option-label crm-editable crmf-label">{$row.label}</td>
-              <td class="crm-custom_option-value disabled-crm-editable" data-field="value" data-action="update">{$row.value}</td>
-              <td class="crm-custom_option-default_value crmf-default_value">{$row.default_value}</td>
-              <td class="nowrap crm-custom_option-weight crmf-weight">{$row.weight}</td>
-              <td id="row_{$id}_status" class="crm-custom_option-is_active crmf-is_active">{if $row.is_active eq 1} {ts}Yes{/ts} {else} {ts}No{/ts} {/if}</td>
-              <td>{$row.action|replace:'xx':$id}</td>
-            </tr>
-          {/foreach}
-          </table>
-        {/strip}
+        </thead>
+      </table>
+      {literal}
+      <script type="text/javascript">
+      CRM.$(function($) {
+        var crmOptionSelector;
+
+        buildOptions();
+
+        function buildOptions() {
+          var sourceUrl = {/literal}'{crmURL p="civicrm/ajax/optionlist" h=0 q="snippet=4&fid=$fid&gid=$gid"}'{literal};
+          var $context = $('.crm-ajax-container');
+          var ZeroRecordText = {/literal}'{ts escape="js"}None found.{/ts}'{literal};
+
+          crmOptionSelector = $('table.crm-option-selector', $context).dataTable({
+              "destroy"    : true,
+              "bFilter"    : false,
+              "bAutoWidth" : false,
+              "aaSorting"  : [],
+              "aoColumns"  : [
+                              {sClass:'crm-custom_option-label'},
+                              {sClass:'crm-custom_option-value'},
+                              {sClass:'crm-custom_option-default_value', bSortable:false},
+                              {sClass:'crm-custom_option-weight'},
+                              {sClass:'crm-custom_option-is_active', bSortable:false},
+                              {sClass:'crm-custom_option-links', bSortable:false},
+                              {sClass:'hiddenElement', bSortable:false}
+                             ],
+              "bProcessing": true,
+              "asStripClasses" : [ "odd-row", "even-row" ],
+              "sPaginationType": "full_numbers",
+              "sDom"       : '<"crm-datatable-pager-top"lfp>rt<"crm-datatable-pager-bottom"ip>',
+              "bServerSide": true,
+              "bJQueryUI": true,
+              "sAjaxSource": sourceUrl,
+              "iDisplayLength": 10,
+              "oLanguage": {
+                             "sZeroRecords":   ZeroRecordText,
+                             "sProcessing":    {/literal}"{ts escape='js'}Processing...{/ts}"{literal},
+                             "sLengthMenu":    {/literal}"{ts escape='js'}Show _MENU_ entries{/ts}"{literal},
+                             "sInfo":          {/literal}"{ts escape='js'}Showing _START_ to _END_ of _TOTAL_ entries{/ts}"{literal},
+                             "oPaginate": {
+                                  "sFirst":    {/literal}"{ts escape='js'}First{/ts}"{literal},
+                                  "sPrevious": {/literal}"{ts escape='js'}Previous{/ts}"{literal},
+                                  "sNext":     {/literal}"{ts escape='js'}Next{/ts}"{literal},
+                                  "sLast":     {/literal}"{ts escape='js'}Last{/ts}"{literal}
+                              }
+                            },
+              "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
+                var id = $('td:last', nRow).text().split(',')[0];
+                var cl = $('td:last', nRow).text().split(',')[1];
+                $(nRow).addClass(cl).attr({id: 'OptionValue-' + id});
+                $('td:eq(2)', nRow).addClass('crmf-default_value');
+                $('td:eq(3)', nRow).addClass('crmf-weight');
+                return nRow;
+              },
 
-        <div class="action-link">
-            {crmButton q="reset=1&action=add&fid=$fid&gid=$gid" class="action-item" icon="circle-plus"}{ts}Add Option{/ts}{/crmButton}
-            {crmButton p="civicrm/admin/custom/group/field" q="reset=1&action=browse&gid=$gid" class="action-item cancel" icon="close"}{ts}Done{/ts}{/crmButton}
-        </div>
+              "fnServerData": function ( sSource, aoData, fnCallback ) {
+                  $.ajax( {
+                      "dataType": 'json',
+                      "type": "POST",
+                      "url": sSource,
+                      "data": aoData,
+                      "success": fnCallback
+                  } );
+              }
+          });
+        }
+      });
+
+      </script>
+      {/literal}
+
+      <div class="action-link">
+          {crmButton q="reset=1&action=add&fid=$fid&gid=$gid" class="action-item" icon="circle-plus"}{ts}Add Option{/ts}{/crmButton}
+          {crmButton p="civicrm/admin/custom/group/field" q="reset=1&action=browse&gid=$gid" class="action-item cancel" icon="close"}{ts}Done{/ts}{/crmButton}
       </div>
     </div>
-
-  {else}
-    {if $action eq 16}
-        <div class="messages status no-popup">
-           <img src="{$config->resourceBase}i/Inform.gif" alt="{ts}status{/ts}"/>
-           {ts}None found.{/ts}
-        </div>
-    {/if}
-  {/if}
+  </div>
 {/if}