Yii Framework Forum: Lazy Loading Type Pager For Clistview Or Cgridview - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Lazy Loading Type Pager For Clistview Or Cgridview Rate Topic: ***** 1 Votes

#1 User is offline   sirius 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 12-October 11

Posted 04 September 2014 - 02:05 AM

Hi All,
I thought of sharing something that I just made. I needed a pager in Yii that would work something like lazy loading. I scoured the internet but didn't find anything suitable. Then I came across few articles which would work as the basis for lazy loading. To make the pager, I did the following:
- extended CBasePager
- extended CListView
- created a view which just showed items
- modified the controller function to return paginated data with ajax

The articles I have followed are:
Extending CListView
Partial rendering in CListView

1. Creating new Pager:
I extended CBasePager class just to create a LOAD MORE button. I have put a span element instead of a tag since a tag would refresh the grid every time it is clicked. The code is as follows:

<?php
/**
 * class TOCPager
 * - extend pager to make pager for TOC for content
 * - add 
 */ 
class exPager extends CBasePager
{
	public function run()
	{
		$currentPage = $this->currentPage;
		$pageCount = $this->pageCount;


		if($currentPage < $pageCount)
		{
			list($controller, $action) = explode('/', Yii::app()->urlManager->parseUrl(Yii::app()->request));
			$theUrl = Yii::app()->request->url;
			//var_dump($this->getOwner());
			echo '
				<div class="load-msg">
					<input type="hidden" id="pgNumber" value="'.($currentPage+1).'"/>
					<span id="paginator">LOAD MORE...</span>
				</div>
			';
			$cs = Yii::app()->getClientScript();
			$script = '
				$("#paginator").click(function(e)
				{
					var containerElement = $(this).parent().parent().parent().attr("id");
					var itemsList = $(this).parent().parent().prev();
					var nextPage = $(this).prev().val()*1;
					var pageCount = '.$pageCount.'*1;

					var pgNumber = $(this).prev();
					$.ajax({
						url:"'.$theUrl.'?ajax="+containerElement+"&page="+(nextPage+1),
						success:function(returnData)
						{
							$(itemsList).append(returnData); //append the content
							pgNumber.val(nextPage+1);

							if(pgNumber.val() == pageCount)
								$("#paginator").parent().attr("style", "display:none;");
						}
					});
				});
			';
			$cs->registerScript('#script', $script, CClientScript::POS_READY);
		}
	}
}


2. Next, I extended CListView just to return the items, not with wrapping tags. The code is as follows:

<?php
Yii::import('zii.widgets.CListView');
class PlainCListView extends CListView
{
	public $preItemsTag = '';
	public $postItemsTag = '';

	public function renderItems()
	{
	    echo $this->preItemsTag."\n";
	    $data=$this->dataProvider->getData();
	    if(($n=count($data))>0)
	    {
	        $owner=$this->getOwner();
	        $render=$owner instanceof CController ? 'renderPartial' : 'render';
	        $j=0;
	        foreach($data as $i=>$item)
	        {
	            $data=$this->viewData;
	            $data['index']=$i;
	            $data['data']=$item;
	            $data['widget']=$this;
	            $owner->$render($this->itemView,$data);
	            if($j++ < $n-1)
	                echo $this->separator;
	        }
	    }
	    else
	        $this->renderEmptyText();
	    echo $this->postItemsTag."\n";
	}

	public function run()
    {
        $this->renderContent();
    }
}


3. Thirdly, I created a small view that uses previously created PlainCListView for showing the list. An example of the view is as follows:

<?php
	$this->widget('application.widgets.PlainCListView', array(
		'dataProvider'=>$posts,
		//'afterAjaxUpdate'=>'clickEvents',
		//'ajaxType'=>'POST',
		'itemView'=>'_post',
		'viewData'=>array('userForumStatus'=>$userForumStatus, 'isLocked'=>$isLocked),
		'summaryText'=>'',
		'id'=>$listID,
		'template'=>'{items}',
	));
?>


4. Lastly, in the controller, I have followed the idea presented here. My sample code is as follows:
		if(Yii::app()->request->isAjaxRequest && isset($_GET['ajax']) && $_GET['ajax'] === $listID) 
		{
			$this->renderPartial('_posts_list_nopager', array(
				'posts' => $posts,
				'listID' => $listID,
				'userForumStatus'=>$userForumStatus,
				'isLocked'=>isset($parentForum['locked'])?$parentForum['locked']:0
			));

			Yii::app()->end();
	    }


So, when you run everything, you will get a pager 'LOAD MORE' at the bottom of the list. If you click it, additional rows/items will be appended to the existing items block.

I hope this is helpful to everybody. I had hell of a time searching for right materials for this.
0

#2 User is offline   Abhishek Shah 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 89
  • Joined: 20-July 12
  • Location:New Jersey,USA

Posted 04 September 2014 - 04:51 AM

Good work!!! This should be in Tips, Snippets and Tutorials Section.
Feel free to ask for help,
Abhishek.
Freelancer.
Yii Basic Gii With Export Pdf Excel
0

#3 User is offline   Maurizio Domba Cerin 

  • Yii - Yesss It Is !!!
  • Yii
  • Group: Yii Dev Team
  • Posts: 4,346
  • Joined: 12-October 09
  • Location:Croatia

Posted 04 September 2014 - 04:59 AM

NOTE: moved to proper section - "Tips, Snippets and Tutorials" instead of "Bug Discussions"
Find more about me.... btw. Do you know your WAN IP?
0

#4 User is offline   Yatin Mistry 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 87
  • Joined: 11-March 14

Posted 04 September 2014 - 05:15 AM

Ver nice. This must be in wikis.

Thanks for sharing.
Yii Posts

Yes !t is.
0

#5 User is offline   sirius 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 15
  • Joined: 12-October 11

Posted 05 September 2014 - 01:35 AM

Thanks everybody!
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users