Yii2 ListView and dataprovider - php

What data must be sended to dataprovider?
In my controller:
public function actionIndex() {
$searchModel = new UserSearch();
$dataProvider = $searchModel->search( Yii::$app->request->queryParams );
//other stuff and sending array of params to view
in a view:
echo ListView::widget( [
'dataProvider' => $dataProvider,
] );
but i got only id`s:
And if i`m set single view like:
'itemView' => '_single',
how send data to _single.php ?
I mean - need default template for view list items like in GridView:
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'username',
'email:email',
'password',
'role',
//....
And then i got perfect grid:

Controller - SiteController.php
<?php
// Yii2 Listview Example : by Songwut Kanchanakosai, Thailand.
use common\models\Members;
use common\models\SearchMembers;
...
public function actionIndex() {
$searchModel = new SearchMembers();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
?>
View (1) - index.php
<?php
use yii\widgets\ListView;
...
echo ListView::widget( [
'dataProvider' => $dataProvider,
'itemView' => '_item',
] ); ?>
View (2) - _item.php
<?php
use yii\helpers\Html;
?>
<?=$model->name;?>
<?=$model->age;?>
<?=$model->mobile;?>
Example Result :
Songwut 36 +668-3949-5153
Prawee 41 +668-7323-2334
Kosol 32 +668-8014-0165
Utehn 39 +668-7874-5643

how send data to _single.php ?
Here is how, use $viewParams
$viewParams public property array $viewParams = []
Additional parameters to be passed to $itemView when it is being
rendered. This property is used only when $itemView is a string
representing a view name.
echo ListView::widget( [
'dataProvider' => $dataProvider,
'viewParams'=>['name'=>'My Name is Stefano'], //acccessed in view as $name with value 'My Name is Stefano'
] );

in official docs http://www.yiiframework.com/doc-2.0/yii-widgets-listview.html#$itemView-detail
$itemView public property
The name of the view for rendering each data item, or a callback (e.g. an anonymous function) for rendering
each data item. If it specifies a view name, the following variables
will be available in the view:
$model: mixed, the data model
$key: mixed, the key value associated with the data item
$index: integer, the zero-based index of the data item in the items array returned by $dataProvider.
$widget: ListView, this widget instance
So your User model data should be available in _single.php as $model->username

So i suppose can use Detail View in _single.php i think:
DetailView::widget([
'model' => $model,
'attributes' => [
'id',
'username',
'email:email',
//....

Related

Q: Yii2 load data from database

I have problems with loading data from database.
My goal is to implement a MVC which dynamically shows in the view the values stored in the db table. So, in the Project model I have this code:
public function search($params)
{
$query = project::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
'id' => $this->id,
'position' => $this->position,
'created_at' => $this->created_at,
'is_deleted' => $this->is_deleted,
]);
$query->andFilterWhere(['ilike', 'title', $this->title])
->andFilterWhere(['ilike', 'description', $this->description])
->andFilterWhere(['ilike', 'link', $this->link])
->andFilterWhere(['ilike', 'image', $this->image]);
return $dataProvider;
}
In the Controller:
public function actionIndex()
{
$searchModel = new SeachProject();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
And in the view (index.php):
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
'title',
'description',
'image',
],
]); ?>
Well, it works but I need to print the values into Uikit cards and not through Gridview limitations (which is actually the only way I know). I should have one card for each record in the table with an image (the url in the image field of the table) and a link (the url in the link field of the table).
Any words of advise would be good, thanks in advance!
You can use ListView and create any kind of structure using UiKit cards or material design.
The ListView widget is used to display data from a data provider. Each
data model is rendered using the specified view file. Since it
provides features such as pagination, sorting and filtering out of the
box, it is handy both to display information to end user and to create
data managing UI.
A typical usage is as follows:
use yii\widgets\ListView;
use yii\data\ActiveDataProvider;
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => '_ui-card',
'viewParams' => [
'fullView' => true,
'context' => 'main-page',
],
]);
The _ui-card view file could contain the following basic card html :
<?php
use yii\helpers\Html;
use yii\helpers\HtmlPurifier;
?>
<div class="uk-card">
<div class="uk-card-header">
<h3 class="uk-card-title"><?= Html::encode ( $model->title ) ?></h3>
</div>
<div class="uk-card-body"><img src="<?= Html::encode ( $model->image ) ?>"><?= Html::encode ( $model->link ) ?></div>
<div class="uk-card-footer"></div>
</div>
This way you can show every project as a separate card using the view file.
Hope this helps

How to add grand total to the bottom of yii2 grid view

I have a grid view which is like this. The columns are calculated with the help of MySQL query and displayed accordingly.
<?php
$subquery = Adanalytics::find()->
select('id,ad_id,date_event,max(cpc) cpclick,max(cpv) cpview,max(impression) impression,max(view) view,max(clicks) clicks,visitor_ip,publisher_id')->
from('ad_analytics')->
where(['publisher_id' => Yii::$app->user->identity->id ])->
groupBy('ad_id,date_event,visitor_ip');
$query=Adanalytics::find()->
select('ad_id,date_event,sum(cpclick) total_click_cost,sum(cpview) total_view_cost,sum(impression) total_impression,sum(view) total_views,sum(clicks) total_clicks,publisher_id')->
from(['t'=>$subquery])->
groupBy('t.ad_id,t.date_event');
?>
<?= GridView::widget([
'dataProvider'=>new ActiveDataProvider([
'query' => $query,
]),
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'ad_id',
'total_impression',
'total_views',
'total_clicks',
'total_click_cost',
'total_view_cost',
'date_event',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
I want to show a grand total column at the bottom of this grid view.
For example
'grand_total_impression',
'grand_total_views', //This is the sum of all displayed views
'grand_total_clicks',//This is the sum of all displayed clicks
'grand_total_click_cost',//THis is the sum of all displayed cost
'grand_total_view_cost',//This is the sum of all displayed view cost
To do that I have code in my controller which is like this.
public function actionIndex()
{
$searchModel = new Adanalytics2Search();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$grandTotal = [];
foreach ($dataProvider->getModels() as $value) {
// var_dump($value);
// exit();
$grandTotal['total_click_cost'] += $value['total_click_cost'];
$grandTotal['total_view_cost'] += $value['total_view_cost'];
}
//var_dump($dataProvider);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'grandTotal' => $grandTotal,
]);
}
But it is producing the error in at this way.
Undefined index: total_click_cost
Where am I going wrong? Or is there any other way to solve this problem?
I strongly advise you to use katrik gridview. It handles page summary much better and implements a lot of other usages. Alternatively add 'showPageSummary' => true at your gridview to display columns summary.
use kartik\grid\GridView;
// Create a panel layout for your GridView widget
echo GridView::widget([
'dataProvider'=> $dataProvider,
'filterModel' => $searchModel,
'columns' => $gridColumns,
'showPageSummary' => true
]);
Similar question: Yii2: Kartik Gridview sum of a column in footer
This has solved the problem anyway.
This in grid column.
[
'attribute'=>'total_impression',
'pageSummary' => true
],
And in grid view
'showPageSummary' => true,

Yii2 : How to pass additional parameters to listview

I read this post and answer give by Songwut K. in this question:
Yii2 ListView and dataprovider
But i want to know that is possible to use second model in _item. Suppose the _item is a post in the forum that retrieves data from the $model but I'd like to use a different model like $comment for me comment on a this post and view the post together with a commentary as one _item. Imagie that item is post on facebook and it display only text, date and user which write this post. But how i can add comment to this from other model? I just want to pass my $comment to _item view.
I was tried add new Commnet in my controller:
public function actionIndex()
{
$model = new NewsForm();
$searchModel = new NewsSearch();
$comment= new UrComment();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->setSort(['defaultOrder' => ['Id'=>SORT_DESC]]);
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$model->saveNews();
return $this->redirect(['/content/news']);
} else {
return $this->render('index', [
'model' => $model,
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'comment' => $comment
]);
}
}
And render this to index. But i can use my $comment only in index how can i pass this to _item? i tried this:
<?php
echo ListView::widget( [
'dataProvider' => $dataProvider,
'itemView' => '_item',
'summary'=>'',
'comment' => $comment
]); ?>
And tried in my _item:
<?= $model->getStatus($model->cnNewsContentType_Id); ?> <br>
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($comment, 'Text')->textInput(['maxlength' => true])->label('Treść') ?>
<?php ActiveForm::end(); ?>
But have error:
Unknown Property – yii\base\UnknownPropertyException
Setting unknown property: yii\widgets\ListView::comment
In _item i can only use $model. It is possible to pass my $comment to _item view? Pls help me
You should simply use viewParams :
Additional parameters to be passed to $itemView when it is being rendered. This property is used only when $itemView is a string representing a view name.
e.g. :
<?= ListView::widget( [
'dataProvider' => $dataProvider,
'itemView' => '_item',
'viewParams' => ['comment' => $comment],
'summary'=>'',
]); ?>

Yii 2.0 Getting data from model without widget

Can anyone give me sample of how to retrieve data from model without having to use Widget ? Because need to get data per table column and put them inside my own view (not using widget)
Controller :
public function actionIndex() {
$searchModel = new B2CProductsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
View :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'sku',
'name',
'short_description',
'long_description',
'thumb_img:ntext',
'large_img:ntext',
'url_content:ntext',
'contact_info',
'status',
'currency',
'price',
'dimension',
'weight',
// 'created',
// 'modified',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
The widget above iterate through the element inside the predefined gridview,
but what I want to do instead is something like :
foreach($data as $ab) {
echo $ab->id;
}
You can do it this way:
/* assuming $data is an ActiveDataProvider object */
$models = $data->getModels();
foreach($models as $model) { ... }
see more here
If you are using an ActiveDataProvider:
Controller:
public function actionMyAction()
{
$dataProvider = new ActiveDataProvider([
'query' => MyModel::find(),
]);
return $this->render('my-results-page', [
'dataProvider' => $dataProvider,
]);
}
View:
<?php
foreach ($dataProvider->models as $model){
echo $model->myProperty;
}
?>
If you are using a query, such as this:
$query = (new \yii\db\Query())
->select('this, that')
->from('over_there');
$command = $query->createCommand();
$rows = $command->queryAll();
Then you can iterate over the result like this(assuming you passed it to the view in a variable called $dataProvider):
foreach($dataProvider as $data)
{
$data['myProperty'];
}

Yii2 Use two Models in one GridView

I have a GridView which displays an employee's summary of his/her payslip. Here's a screenshot for more understanding:
Those highlighted columns come from a different model which is the User model while the rest come from the Payslip model.
How do I merge 2 models in one GridView? Because in GridView, it is more likely for you to have a single model to display data. But how about 2 models?
Here's a code in my Payslip model, note that getUser() is generated with gii since user_id is a foreign key in my payslip table:
public function getUser()
{
return $this->hasOne(User::className(), ['user_id' => 'user_id']);
}
public function getFirstName()
{
return $this->user ? $this->user->fname : 'First Name';
}
public function getLastName()
{
return $this->user ? $this->user->lname : 'Last Name';
}
The Payslip controller:
public function actionIndex()
{
$searchModel = new PayslipSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
And then the Payslip view:
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
//'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'payslip_id',
//'store_id',
'firstName',
'lastName',
'total_earnings',
'total_deduction',
'net_pay',
['class' => 'yii\grid\ActionColumn'],
],
]);
?>
BTW, in this example, I just created payslip #1 manually to give you a demo.
Additional info:
The logged in user is a BizAdmin user, and all of BizAdmin's staff users should be displayed in the payslip table (that table above) even if these staff users still don't have any payslip created for them. So by default, that table will be occupied already with staff users under the logged in BizAdmin user, and those staff users who still have no payslips created will be indicated "Create Payslip"
Here's an example in KashFlow:
Update view to:
<?php
echo GridView::widget([
'dataProvider' => $dataProvider,
//'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'payslip_id',
//'store_id',
['value' => function ($data) {return $data->getFirstName();}, 'label' => 'First Name'],
['value' => function ($data) {return $data->getLastName();}, 'label' => 'LastName'],
'total_earnings',
'total_deduction',
'net_pay',
['class' => 'yii\grid\ActionColumn'],
],
]);
?>
And in $searchModel->search add you relation, like that:
$query = Payslip::find()->with(['user']);
Read for data column - http://www.yiiframework.com/doc-2.0/guide-output-data-widgets.html#data-column

Categories