程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> yii_CGridView_ajax_pagination_and_ajax_sort

yii_CGridView_ajax_pagination_and_ajax_sort

編輯:關於PHP編程

本文主要內容: 1, 正常情況下 CGridView 實現 Ajax 分頁和排序的原理 2, 分頁和排序無法Ajax的情況分析 3, 自定義分頁(重寫CLinkPager)後如何實現 Ajax 分頁和排序 /*** author: php攻城師 http://blog.csdn.net/phpgcs ***/     [php]   <?php    $this->widget('zii.widgets.grid.CGridView', array(       'id'=>'keyword-grid',       'dataProvider'=>$model->search(),       'cssFile'=>false,       'template'=>'{items} <div class="page_area">{pager} {summary}</div>',       'pager'=>array('cssFile'=>false),       'ajaxUpdate'=>true,       'columns'=>array(           array(               'name'=>'leader_name',               'value'=>'$data->event',               'header'=>'關鍵詞名稱',               'headerHtmlOptions'=>array('width'=>'130px'),           ), .... ....   以上代碼實現一個常規的 CGridView , 除了 pager 用了自定義的樣式。。   而在頁面的源代碼中,我來找出相關的部分:   [javascript]   <script type="text/javascript" src="/chuanmei/assets/f5d36ac5/jquery.ba-bbq.js"></script>   [javascript] view plaincopyprint? <script type="text/javascript" src="/chuanmei/assets/fb90bba/gridview/jquery.yiigridview.js"></script>   <script type="text/javascript">   /*<![CDATA[*/   jQuery(function($) {   jQuery('#keyword-grid a.delete').live('click',function() {       if(!confirm('確定要刪除這條數據嗎?')) return false;       var th=this;       var afterDelete=function(){};       $.fn.yiiGridView.update('keyword-grid', {           type:'POST',           url:$(this).attr('href'),           success:function(data) {               $.fn.yiiGridView.update('keyword-grid');               afterDelete(th,true,data);           },           error:function(XHR) {               return afterDelete(th,false,XHR);           }       });       return false;   });   jQuery('#keyword-grid').yiiGridView({'ajaxUpdate':['1','keyword-grid'],'ajaxVar':'ajax','pagerClass':'pager','loadingClass':'grid-view-loading','filterClass':'filters','tableClass':'items','selectableRows':1,'pageVar':'keyword_page'});   });   /*]]>*/   </script>     其中會發現 yii 自動加載了 jquery.ba-bbq.js  &&  jquery.yiigridview.js ,以及2段 代碼 其中一段是用來實現  刪除 一行數據時 彈出提示框 讓用戶 確認是否刪除 功能 的; 一段是最核心關鍵的 用於 ajax update grid 的, 也正是這部分 代碼 實現了 ajax 的翻頁 和 排序。   /*********** 我是分割線 *******************************/   如果發現 點擊了 分頁 或者 排序 後,不是ajax 方式的(也就是你可以 在 地址欄 中 看到 每次 請求的常常的 url ) 一個要檢查的地方: ajaxUpdate=>'', 這個參數 updateSelector=>'', 這個參數   /*********** 我是分割線 *******************************/   一般情況下,CLinkPager都無法滿足我們的需求,要重寫; 而重寫我這裡提供3種方式: 1, 禁用 CGridView自己的Pager ,在 CGridView 之外 自己寫 2, 禁用 CGridView自己的Pager ,重寫 CGridView 文件, 將 自己的pager 寫在     public function renderItems() 中 3, 配置 CGridView 的 pager 參數。   如下是默認的 CLinkPager 的樣子 翻頁:  < 前頁 1 2 3 後頁 >   現在我們想要如下的Pager 效果 第 31 - 40 條, 共 14546 條     上一頁 1 2 3 4 5 6 7 8 9 10 下一頁       /*** author: php攻城師   ***/   先看第1種重寫方案:   重寫 CLinkpager 如下: [php]   $this->widget('CLinkPager', array(       'header'=>'第 '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+1).       ' - '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+$paginationTop->getPageSize()).       ' 條, 共 '.$paginationTop->getItemCount().' 條  ',       'pages' => $paginationTop,       'itemCount'=>$totalItemFoundCount,       'prevPageLabel' => '上一頁',       'cssFile'=>false,       'nextPageLabel' => '下一頁',       'footer'=>'  ',   ));      其中的 pagination 在 controller 中生成 [php]  $paginationTop = new CPagination($totalItemFoundCount);   $paginationTop->pageSize= $pageSize;     然後把重寫的 CLinkPager 放在  CGridView 前面即可。 運行後發現一個Bug ,就是 分頁 不是 Ajax 的。 不是Ajax的不要緊, 關鍵是 分頁和排序不能結合使用了。 原因很簡單, 分頁不是ajax 的,而排序是ajax 的, 兩個 請求發出後 url 不在一個地方, 那麼分頁參數和 排序參數就 不再一地方, 當然無法結合使用。 解決方案: 統一起來。 要麼統一為url排序&分頁, 要麼統一為ajax排序&分頁。 url的簡單, 設置 ajaxUpdate=>false, ajax的也簡單, 只要理解了本文第一部份說的 ajax 排序的原理, 之所以不能夠 ajax 分頁, 是因為我們的分頁是 重寫了, 而且還放在了CGridView 之外, 這樣如何讓  jQuery('#keyword-grid').yiiGridView({'ajaxUpdate':['1','keyword-grid'],'ajaxVar':'ajax','pagerClass':'pager','loadingClass':'grid-view-loading','filterClass':'filters','tableClass':'items','selectableRows':1,'pageVar':'keyword_page'});   ajaxUpdate的時候 還去照顧到你寫在外面的 CLinkPager 呢? 配置2個參數:                     'ajaxUpdate'=>'datalist-grid, yw0',                     'updateSelector'=>'.pager a, thead th a',   本來 ajaxUpdate 的作用范圍 只是  datalist-gird , 現在我們告訴他 還要 作用在我們重寫在grid 外面的 分頁 ul  ,其id 是 yw0. updateSelector 指定了 觸發 ajaxUpdate 這個動作的html元素, 也是要保證 包含了 分頁的鏈接和排序的鏈接 , 否則也是無法成功 ajax 排序/分頁。   再看第2種重寫方案:   上面第一種方案 太復雜了把, 既然問題的核心關鍵是 沒有把自定義的 ClinkPager 放在 CGridView 中, 那我們就重寫 CGridView將其放進去呗。 對,確實是可行的。   [php]   <?php   Yii::import('zii.widgets.grid.CGridView');      class EbuCGridView extends CGridView   {       /**            * Renders the data items for the grid view.       */            public function renderItems()       {              if($this->dataProvider->getItemCount()>0 || $this->showTableOnEmpty)           {                  $this->renderCustomerPager();               echo "<table class=\"{$this->itemsCssClass}\">\n";               $this->renderTableHeader();               ob_start();               $this->renderTableBody();               $body=ob_get_clean();               $this->renderTableFooter();               echo $body; // TFOOT must appear before TBODY according to the standard.               echo "</table>";               $this->renderCustomerPager();           }                  else                       $this->renderEmptyText();       }                             public $paginationTop;       public $totalItemCount;       public $totalItemFoundCount;       public function renderCustomerPager()       {                              $paginationTop = $this->paginationTop;           $totalItemCount = $this->totalItemCount;           $totalItemFoundCount = $this->totalItemFoundCount;           echo '<div class="page_area" style="text-align:right;">';           echo '<div class="pager">';           $this->widget('CLinkPager', array(               'header'=>'第 '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+1).               ' - '.($paginationTop->getCurrentPage()*$paginationTop->getPageSize()+$paginationTop->getPageSize()).               ' 條, 共 '.$paginationTop->getItemCount().' 條  ',               'pages' => $paginationTop,               'itemCount'=>$totalItemFoundCount,               'prevPageLabel' => '上一頁',               'cssFile'=>false,               'nextPageLabel' => '下一頁',               'footer'=>'  ',           ));                        ....       第3種方案:   前2種方案,說實話,都太麻煩了,破壞了yii 自身的機制, 又在其上彌補了半天。。   最好的方案 ,還是 配置 CGridView 的 'pager' ,來實現我們要更復雜的CLinkPager的目標。   但是,有些時候還真必須用第 1、2種方案; 比如我應用的情況是: 用 Coreseek 全文索引 查詢出 數據 的id ,再 用 id 來到數據庫中找出數據,形成 CActiveDataProvider ,最後用 CGridView來展示。   我這裡的 CDbCriteria 如下 [php]   $criteria = new CDbCriteria;   $criteria->join  = 'LEFT JOIN site2 AS si** ON t.**=**.domain_hash';   $criteria->addInCondition('t.id', $IDARRAY);   $criteria->select = array("t.id", "t.content", "t.pubtime", "t.url", "t.reply_num", "t.retweet_num", "site_config.site_name");   $criteria->order = 'FIND_IN_SET(t.id, "'.join(",", $IDARRAY).'")';     其中 變量 IDARRAY 正是 coreseek 得到的 一個 id 組成的數組 如果按照 普通的   [php]   $dataProvider = new CActiveDataProvider('TData', array(       'criteria'=>$criteria,       'pagination'=>array(           'pageSize'=>10,       ),      ));       是不滿足我的需求的。 因為我的分頁和排序都是在 coreseek 中完成的, 這裡用 CActiveDataProvider 只是提供了當前頁(比如每一頁10條記錄)的10條記錄。   end。 有更好的建議和意見,歡迎提出共同學習。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved