Access variable in Gridview function yii2 - php

I am trying to access a variable on view file into Gridview but it is throwing error that it should be array but null given i am declaring $totalDays on top of my view file and i am using it in Gridview like below
[
'attribute' => 'class_id',
'format' => 'raw',
'label' => "Class Date",
'value' => function ($model) {
array_push($totalDays,$model->class->date);
return $model->class->date;
},
'footer'=> '<span>Total Days</span>',
],
But it throws following error
array_push() expects parameter 1 to be array, null given

To explain, $totalDays is not available in the widget because the whole function only gets run when the widget is rendered, $totalDays is no longer declared. As #arogachev hinted above, you will need to make $totalDays in your model, then you can access it. Try this in your model;
public function getTotalDays(){
//Your logic here to generate totalDays
return $totalDays;
}
Then you can use it in your view like this;
[
'attribute' => 'class_id',
'format' => 'raw',
'label' => "Class Date",
'value' => function ($model) {
array_push($model->totalDays, totalDays,$model->class->date);
return $model->class->date;
},
'footer'=> '<span>Total Days</span>',
],

Insert use after function signature in value callable function:
[
'attribute' => 'class_id',
'format' => 'raw',
'label' => "Class Date",
'value' => function ($model) use($totaleDays) {
array_push($totalDays,$model->class->date);
return $model->class->date;
},
'footer'=> '<span>Total Days</span>',
],

As #Fabrizio said. Insert use after function signature in value callable function:
'value' => function ($model) use($totaleDays) {
array_push($totalDays,$model->class->date);
return $model->class->date;
},
For multiple value to pass in to value function you can use as below.
'value' => function ($model) use($var1, $var2....., $varN) {
array_push($totalDays,$model->class->date);
return $model->class->date;
},
Like this use($var1, $var2....., $varN)

While you can definetely pass this variable through use section of closure, it's wrong in your code. MVC principle is violated, because view it's only for display, and you exposing logic such as array_push.
I'd recommend to refactor it and place data calculation in model, so you can simply call return $model->yourMethod(); and it will return desired data.

Related

Yii2 GridView attribute format defined by different attribute value

I would like to define the format of an attribute in GridView based on a db field value. I was trying for example like this:
'format' => function ($model) {return $model->format;}, // it should return 'boolean'
but I have tried many other ways also, but it's not working. I'm getting:
PHP Notice – yii\base\ErrorException
Trying to get property of non-object
If I'm simply returning format as an attribute, it's working without any issues. It seems that it's not accepting it in the format section.
Is it possible anyways what I'm trying to achieve? Can you please point me to the right direction?
Closures for format are not supported. You may use raw format and do formatting in Closure for value:
[
'attribute' => 'name',
'type' => 'raw',
'value' => function ($model) {
$format = 'as' . ucfirst($model->format);
return Yii::$app->formatter->$format($model->name);
},
],
Refer Yii2 Formatter
Example:
<?= GridView::widget([
'id' => 'grid-list',
'dataProvider' => $dataProvider,
[
'attribute' => 'format_date',
// 'format' => 'raw',
'value' => function ($model) {
// Here use \Yii::$app->formatter->asDate();
// Ex: return \Yii::$app->formatter->asDate($model->format_date);
return \Yii::$app->formatter->asDate($model->format_date);
},
],
]) ?>

Yii2 type cast column as integer

In Yii2, I have a model, for example Product. What I want to do is select an extra column from the database as int
This is an example of what I'm doing:
Product::find()->select(['id', new Expression('20 as type')])
->where(['client' => $clientId])
->andWhere(['<>', 'hidden', 0]);
The problem is, I'm getting the result as "20". In other words, 20 is returned as string. How can I make sure that the selected is Integer?
I tried the following also but its not working:
Product::find()->select(['id', new Expression('CAST(20 AS UNSIGNED) as type')])
->where(['client' => $clientId])
->andWhere(['<>', 'hidden', 0]);
You can manually typecast in Product's afterFind() function or use AttributeTypecastBehavior.
But above all, you'll have to define a custom attribute for alias you use in the query. For example $selling_price in your Product model if you use selling _price as an alias.
public $selling_price;
After that, you can use any of the following approaches.
1) afterFind
Example Below
public function afterFind() {
parent::afterFind();
$this->selling_price = (int) $this->selling_price;
}
2) AttributeTypecastBehavior
Example below
public function behaviors()
{
return [
'typecast' => [
'class' => \yii\behaviors\AttributeTypecastBehavior::className(),
'attributeTypes' => [
'selling_price' => \yii\behaviors\AttributeTypecastBehavior::TYPE_INTEGER,
],
'typecastAfterValidate' => false,
'typecastBeforeSave' => false,
'typecastAfterFind' => true,
],
];
}

how to use function in DetailView yii2

**i use model function in detail view how i use function in detail view **
<?= DetailView::widget([
'model' => $model,
'attributes' => [
'title',
'demand',
'sell_for',
'property_category',
'detail',
[
'attribute' => 'dealer_id',
'format'=>'raw',
'value'=> function ($model) {
return Dealer::getName($model->dealer_id);
}
],
],
]) ?>
**i use model function in detail view how i use function in detail view **
In DetailView value don't need anonymous function but only the assign ..
[
'attribute' => 'dealer_id',
'format'=>'raw',
'value'=> Dealer::getName($model->dealer_id);
],
see yii2 doc
return Dealer::getName($model->dealer_id)
Write out the code inside the getName function. If you want to get the name of the dealer using its id, then I think you should use the yii\db\ActiveQuery to sort that out. Lemme see your getName function

Yii2 how to anchor the value of the relationship in the GridView

I am beginner. I explain the topic:
there is this relationship in the Ticket model:
public function getTyp()
{
return $this->hasOne(Typology::className(), [ 'id' =>'typ_id']);
}
and in the ticket table there is the typ_id column (it is in relationship with the id of the Typology table).
In the view views/ticket/index.php there is GridView::widgetwith these columns:
[
'attribute' => 'typ_id',
'value' => 'typ.typology'
],
I want to anchor the value of the relationship.
I have tried this:
[
'attribute' => 'typ_id',
'value' => function ($model) {
return Html::a (
'typ.typology',
'/typology/view?id='.$model->typ_id
);
}
]
but it doesn't work
someone can help me?
Html::a() interprets typ.typology as raw string. Use $model in value closure to get necessary property through relation.
Also instead of manually concatenate the url with its parameters, just pass them in array (see Url::to() to understand how link is constructed).
[
'attribute' => 'typ_id',
'value' => function ($model) {
return Html::a($model->typ->typology, ['/typology/view', 'id' => $model->typ_id]);
},
],

yii2:data of related model in Gridview

I have two models namely MedicineRequestEntry and MedicineRequest. MedicineRequestEntry is related to MedicineRequest via
public function getMedicineRequests()
{
return $this->hasMany(MedicineRequest::className(),
['medicine_request_entry_id' => 'id']);
}
Now in grid-view of MedicineReuestEntry I am trying to pull the data from MedicineRequest Model using the relation using two alternative ways
like
[
'attribute' => 'is_delivered',
'value'=> 'medicineRequests.is_delivered'
],
In this method I am getting the value as not set.
and another method:
[
'attribute' => 'is_delivered',
'value'=> '$data->medicineRequests->is_delivered'
],
In this method I am getting the error like:
Getting unknown property: app\models\MedicineRequestEntry::$data->medicineRequests->is_delivered
Now I need some help, what I am doing wrong here.
Thank you.
You should use a callback function, see the guide:
[
'value' => function ($data) {
$str = '';
foreach($data->medicineRequests as $request) {
$str .= $request->is_delivered.',';
}
return $str;
},
],
Or for the first result of the array:
[
'value' => function ($data) {
return $data->medicineRequests[0]->is_delivered;
},
],

Categories