I have a search form, which returns a bunch of images. Because their number can be high, I would prefer having the results displayed using pagination. However, I cannot seem to get it to work properly. I have moved everything to the view to keep things as simple as possible.
Here is my code snippet for the search and pagination:
$searchData = $model->search(); // this is the result of the search
$pages = new CPagination($searchData->itemCount);
$searchData->setPagination($pages);
$pages->applyLimit($searchData->criteria);
$pages->pageSize = 2;
Then, I display the results using a "foreach" statement:
foreach($searchData->getData() as $data)
{
// results displayed here
}
Finally, I have the CLinkPager widget:
$this->widget('CLinkPager', array(
'pages' => $pages,
'header' => 'Отиди на страница: ',
'nextPageLabel' => 'Следваща',
'prevPageLabel' => 'Предишна',
)); `
The problem is: there is not a relation between the widget and the displayed results.
For instance, if I get 4 results, the widget correctly shows that there are 2 pages. However, the results are not displayed in two pages, all are shown in one and clicking the CLinkPager links does nothing.
I have done pagination in the past successfully before, but for all the data using
model()->findAll().
How do I state the relation between the pagination widget and the search results... ?
Thank you for your time.
I think you are possibly overcomplicating the process. You could more easily use CListView widget to display your results with pagination.
Your controller may have this;
public function actionIndex(){
$model = new Model;
$this->render('index', array('model' => $model);
}
Your model needs to have a search method that returns an instance of CActiveDataProvider, for example
public function search() {
$criteria = new CDbCriteria;
$criteria->compare('id', $this->id, true);
$criteria->compare('title', $this->title, true);
$criteria->order = 'sortOrder';
return new CActiveDataProvider($this, array(
'criteria' => $criteria,
));
}
Then in your view file you can use this code;
$this->widget('widgets.CListView', array(
'dataProvider' => $model->search(),
'itemView' => '_list',
'template' => '{pager}{items}',
'pager' => array(
'nextPageLabel' => 'Следваща',
'prevPageLabel' => 'Предишна',
)
));
You can extend the CListView by putting this in your extensions folder, and change the page size there.
<?php
Yii::import('zii.widgets.CListView');
class CustomListView extends CListView {
public function init() {
if ($this->dataProvider !== null)
$this->dataProvider->pagination->pageSize = 30;
$this->dataProvider->pagination->nextPageLabel => 'Следваща';
$this->dataProvider->pagination->prevPageLabel => 'Предишна';
parent::init();
}
}
Then, use the CustomListView as follows:
<?php $this->widget('CustomListView', array(
'dataProvider'=>$dataProvider,
'itemView'=>'_view',
)); ?>
You do not need to use CLinkPager widget directly this way.
Related
I would like to add pagination to my website, but I am very new to Yii and would like some advise.
This is the page that I am looking to add pagination: https://gocar2.com/newsproducts/center
As you can see I have numerous cells for each auto news, and now I am allowing only 18 news to show on the page. I would like to add pagination here so that I can browse more news.
And this is what I tried:
newscontroller.php
<?php
use yii\data\Pagination;
class NewsproductsController extends Controller
{
public function actionCentermore()
{
$criteria = new CDbCriteria;
$criteria->addCondition("approvedStatus = '1'");
$criteria->order = 'createdDate DESC';
$product = Newsproducts::model()->findAll($criteria);
$Pagination = new Pagination([
'defaultPageSize' => 15,
'totalCount' => $product->count(),
]);
$products = $product->offset($Pagination->offset)
->limit($Pagination->limit)
->all();
$this->renderPartial('centermore',compact('products', 'Pagination'));
}
}
newsview.php will render all the top menu and banners and it will render centermore.php
$this->renderPartial('centermore', compact('products', 'Pagination'));
centermore.php (view of the news cells), I then added the LinkPager widget at the bottom.
LinkPager::widget(['Pagination' => $Pagination])
And of course, there is an error, Class LinkPager cannot be found.
Can anyone give me some advise how to solve this/implement paging?
In Yii2 pagination is usually handled via DataProvider, have a look at the:
Yii2 Guide: Data Providers, especially ActiveDataProvider:
use yii\data\ActiveDataProvider;
$query = Post::find()->where(['status' => 1]);
$provider = new ActiveDataProvider([
'query' => $query,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'defaultOrder' => [
'created_at' => SORT_DESC,
'title' => SORT_ASC,
]
],
]);
// returns an array of Post objects
$posts = $provider->getModels();
I have one web page and in this page I need total 2 paginations for different different 2 tables.
I have tried with different pagination but it's dependent with each other.
For ex., If I select second page of first table then second table automatically changed with 2nd page.
Here is my controller code code :
$page = $this->pageForPagination('User');
$this->paginate = array(
'User' => array(
'fields' => array(
'User.*',
),
'conditions' => $userConditions,
'page' => $page,
),
);
$this->set('users', $this->paginate('User'));
$page1 = $this->pageForPagination('Game');
$this->paginate = array(
'Game' => array(
'fields' => array(
'Game.*',
),
'conditions' => $conditions,
'page' => $page1,
),
);
$this->set('games', $this->paginate('Game'));
Here is the function that is used in above code :
function pageForPagination($model) {
$page = 1;
$sameModel = isset($this->params['named']['model']) && $this->params['named']['model'] == $model;
$pageInUrl = isset($this->params['named']['page']);
if ($sameModel && $pageInUrl) {
$page = $this->params['named']['page'];
}
$this->passedArgs['page'] = $page;
return $page;
}
Here is my view code :
echo $this->element('paging', array('model' => 'User'));
echo $this->element('paging', array('model' => 'Game'));
I have referred above code from this url : http://debuggable.com/posts/how-to-have-multiple-paginated-widgets-on-the-same-page-with-cakephp:48ad241e-b018-4532-a748-0ec74834cda3
Can any one help me because I didn't get any solution still?
The solution in the link you mentioned is to override the default pagination urls and doesn't display both models at the same time. You haven't implemented the solution completely.
You have to extract the page number manually for each model like this:
function pageForPagination($model) {
if (isset($this->params['named']['pagefor'.$model])
return $this->params['named']['pagefor'.$model];
else
return 1;
}
The code below:
echo $this->element('paging', array('model' => 'User'));
echo $this->element('paging', array('model' => 'Game'));
causes the cakephp to use the default pagination view and the urls in the default pagination are the same for both models. You have to use custom pagination view and specify the model for the page link.
For the edited function above you can use a url pattern like this:
/Controller/Action/pageforUser:215/pageforGame:35
for each page link in your view.
I think best practice to use this url pattern is to override the pagination helper so that the links that are created form the following pattern:
'/Controller/Action/pagefor[Model]:215'.[other parameters]
I am developing this yii application and in the index i am displaying a "preview" of these items and currently it is display 8 items then it will pageinate itself. I would like make it page every 4 items and i have searched online and found that i could use the CPagination. I have followed the example in the documentation http://www.yiiframework.com/doc/api/1.1/CPagination and it is working but i don't know how to display the model i have the following code in the index.
foreach($models as $model):
endforeach;
$this->widget('CLinkPager', array(
'pages' => $pages,
));
Also the data that i want to display is Title, Content, Image and id and can i use the _view since i have everying set from there regarding css.
Also by defult the yii application display the index with a CListView is there a way where i can set the item limit there instead of using CPagination
If you want to just display 4 items on the index page, edit the index action like this:
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('{Model}',
array(
'criteria' => array(
'select' => 'title_field,content_field,image_field',
'limit' => {Limit},
)
));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
}
This code will return {Limit} models from the database, if you want to sort them by any field you will need to add 'order' to the criteria array lik this:
'criteria' => array(
'select' => 'title_field,content_field,image_field',
'order' => 'download_id DESC',
'limit' => {Limit},
)
In your view, use foreach and render partial to render the _view.
foreach($models as $model):
$this->renderPartial('//{Model}/_view', $model);
endforeach;
Hope that helps.
This is my first time working with Yii Framework.
I have a model called apartment.
Is it possible to combine the edit form and display view of the apartment in one page?
Here is the code in the view controller
public $modelName = 'Apartment';
public function actionView($id = 0) {
Yii::app()->bootstrap->plugins['tooltip'] = array(
'selector'=>' ',
'options'=>array(
'placement'=>'top',
),
);
$this->render('view', array(
'model' => $this->loadModelWith(array('windowTo', 'objType', 'city')),
'statistics' => Apartment::getApartmentVisitCount($id),
));
}
In your view file add something like -
$this->renderPartial( '_form', array( 'data' => $yourmodel ) )
_form being your edit subview.
Please post more of your code so stack overflow users can help with your specific problem.
look at this for more detail -
http://www.yiiframework.com/doc/api/1.1/CController#renderPartial-detail
and this -
http://www.yiiframework.com/forum/index.php/topic/23012-understanding-render-and-renderpartial/
In my project I want to change the link url because it does not look good.
The link is as example below:
http://www.example.com/product?Product[pagesize]=24&page=2
http://www.example.com/product?Product[brand_id][]=3
so I want to the url like this
http://www.example.com/product?pagesize=24&page=2
http://www.example.com/product?brd[]=3
I use Yii framewrok, so is it possible to change it?
Thank you!
I do not know why u use difficult url instead of dataprovider of yii for paging. here is code:
controller:
$pageSize=5;
$news = News::model()->findAll(); //returns AR objects
$count = count($news);
$dataProvider= new CArrayDataProvider($news, array(
'sort'=>array('attributes'=>array('title')), //you can sort here if objects not sorted
'pagination'=>array('pageSize'=>$pageSize),
));
$models = $dataProvider->getData();
$this->render('index', array(
'models' => $models,
'dataProvider' => $dataProvider,
'itemCount' => $count,
));
on view:
<?php
$this->widget('CLinkPager', array(
'pages'=>$dataProvider->pagination,
));
?>