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,
));
?>
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();
So I have a dataprovider which is created in a controller like this:
$modelSearch = new SearchModel();
$data_provider = $modelSearch->search(Yii::$app->request->queryParams); // returns the data provider
Then I use the $data_provider in a view like this:
GridView::widget([
'dataProvider' => $data_provider,
'export' => false,
'columns' => [
...
],
...
But now I'd like to use the same data from the $data_provider but without pagination and other sorting specifications.
Tried this but doesn't work:
$data_provider->sort = ['defaultOrder'=> ['column_a' => SORT_ASC, 'column_b' => SORT_DESC]]
$data_provider->pagination = false;
I think that's because the data is already retrieved with the ->search() method. Do I need to create a whole new search model class? just to get a different sorting?
Thanks in advance!
You should use two dataProvider eg:
$modelSearch = new SearchModel();
$data_provider = $modelSearch->search(Yii::$app->request->queryParams);
$data_provider2 = $data_provider;
$data_provider2->pagination = false;
$data_provider2->sort = ['defaultOrder'=> ['column_a' => SORT_ASC, 'column_b' => SORT_DESC]]
return $this->render('your_view', [
'searchModel' => $searchModel,
'dataProvider' => $data_provider,
'dataProvider2' => $data_provider2,
]);
Before I asked the question I didn't know the dataProvider already retrieved the data on creation. So altering properties of the dataProvider doesn't do another search, it does different sorting but with the same data it already retrieved.
Answer:
I ended up making a new method in the searchModel class like this:
public function searchByCreatedAt() {
$query = Model::find()->orderBy(['created_at' => SORT_ASC]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
'pagination' => false,
]);
...
}
I have a gridview inside the modal popup. I tried to sort the grid view columns inside the model popup. i tried with Pjax but it changes the page url.
I want to sort gridview in the modal popup without changing the url.
Code:
<?php \yii\widgets\Pjax::begin();
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'id' => 'data_lines_tables',
'columns' => [
[
'name',
'id'
]
]
]);
\yii\widgets\Pjax::end();?>
By default, Pjax will use pushState to update url, you should simply disable this by using :
\yii\widgets\Pjax::begin(['enablePushState' => false]);
Read more about Pjax widget.
Hi there are two ways to do sorting for Cgridview in Modal popup, I have tried in bootstrap modal popup.
Try using the CSort. Please remember, they keys in in $sort->attributes should match columns in the CGridView:
public function actionIndex(){
$sort = new CSort();
$sort->attributes = array(
'employee'=>array(
'asc'=>'employee.name',
'desc'=>'employee.name desc',
),
'company'=>array(
'asc'=>'company.company_name',
'desc'=>'company.company_name desc',
),
);
$dataProvider=new CActiveDataProvider('job', array(
'criteria'=>array('Criteria goes here'),
'sort'=>$sort,
));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
You can also use the sort like this, if u want to sort according to time or id whatever you choose according to your fields in database.
$dataProvider=new CActiveDataProvider('job', array(
'criteria'=>array('Criteria goes here'),
'sort'=>array(
'defaultOrder'=>'createTime DESC',
),
));
Working with Yii framework 2.0 I tried to use the pagination feature and linkpager widget, following Yii documentation.
Below is my controller.
public function actionIndex()
{
$query = Country::find();
$pagination = new Pagination([
'defaultPageSize' => 5,
'totalCount' => $query->count(),
]);
$countries = $query->orderBy('name')
->offset($pagination->offset)
->limit($pagination->limit)
->all();
return $this->render('index', [
'countries' => $countries,
'pagination' => $pagination,
]);
}
In my index view, I use the following code.
<?= LinkPager::widget(['pagination' => $pagination]) ?>
Now I want to add one more pagination feature and LinkPager widget for another model City. In the actionIndex() method I follow the existing code, just create an object of City and an object of new Pagination and return it to the view. In the view I include LinkPager widget once again with another pagination variable $paginationCity. When I click on a pagination number I saw the query string page=xx in the URL. I notice that it is being used for both models Country and City. How can I use multiple pagination on one same page?
You can do it by changing pageParam property of Pagination class:
$cityPagination = new Pagination([
...
'pageParam' => 'city-page',
]);
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.