I have gridview with some columns. I want to create one colums like
'columns' => [
['class' => 'yii\grid\SerialColumn'],
['header' => 'Manager',
//'value' => 'first'],
Column name is Manager and all fields equels 'first'? How could I do this?
Based on info provided, this is easy to achieve with custom grid column:
<?php
namespace app\components;
class CommonValueColumn extends Column
{
public $commonValue = 'Default value for common value';
protected function renderDataCellContent($model, $key, $index)
{
return $commonValue;
}
}
Then use it in GridView widget like this:
'columns' => [
// ...
[
'class' => 'app\components\CommonValueColumn',
'header' => 'Manager',
'commonValue' => 'First',
],
// ...
],
Note that if the manager is a model attribute and the value needs to be taken from database, this is a wrong way to do it.
Information about GridView widget is available in the official docs.
Related
To show my GridView I use this ActiveDataProvider:
public function search($params)
{
$query = PublicationsPublication::find()
->select(['eid', 'title', 'pubdate', 'citedby', "STRING_AGG(DISTINCT(CONCAT(author.authid, ' - ', authname)), ', ') AS authors"])
->joinWith('publicationsAuthor')
->groupBy(['eid','title','pubdate','citedby']);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
...
}
I can't figure out how to use the column generated by the STRING_AGG() function in the Gridview.
Just in case is needed, the publicationsAuthor relation is coded this way:
public function getPublicationsAuthor() {
return $this->hasMany(PublicationsAuthor::className(), ['authid' => 'authid'])
->viaTable('publications.pub_author', ['pubid' => 'id']);
}
I need to use the STRING_AGG() function because I want to show many authors in one cell of the Gridview.
I tried to use the "authors" column in this way:
$gridColumns = [
[
'class' => 'kartik\grid\SerialColumn',
'width' => '20px',
],
'eid',
'title',
'pubdate',
'citedby',
'authors',
];
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => $gridColumns,
'pager' => [
'firstPageLabel' => 'First',
'lastPageLabel' => 'Last'
],
...
]);
But unfortunately it didn't work. In the Grid all the values are set to "not set". The query works great because I tested it in PgAdmin.
yii\data\ActiveDataProvider works with models so only fields defined by model are available by default. The easiest way to add field generated by some expression is to add public property with same name to your model like this:
class PublicationsPublication extends ActiveRecord
{
public $authors;
// ... other code in PublicationsPublication model ...
public function attributeLabels()
{
// You can also add label for new field
return [
'authors' => 'Authors',
// ... other labels ...
];
}
}
The public property $authors will be loaded with data from field authors in the result of your SQL query. Then you can use it in grid as any other field.
The other option is to use yii\data\SqlDataProvider instead of yii\data\ActiveDataProvider.
I want to make the list of table who have relation only, example:
Table:
Order
Process
In ProcessCrudController I want to replace the Process list view into Order list view that only have relation (order-process).
The solution I've tried:
Create new function in OrderCrudController return view($this->crud->getListView(), $this->data);
then, addClause using $request->type URL
The problem of that solution:
Not showing the action row in table
Easy to show all query if we try to remove URL
I really want to make the list view of Process that only already have relation to Order, or any suggestion/idea to make this happen?
NB: I'm struggling at this problem I didn't found the solution, help me please
EDIT (Adding Code):
OrderCrudController:
protected function setupListOperation()
{
// This is the solution that I described before
// $request = request();
// $this->crud->addClause('where', 'user_id', '=', $request->type ?? 1);
$this->crud->addColumns([
[
'name' => 'personal_name',
'label' => 'Name',
'type' => 'text',
],
[
'name' => 'notes',
'label' => 'Catatan',
'type' => 'textarea',
],
[
'name' => 'user_id',
'label' => 'Dibuat oleh',
'type' => 'select',
'entity' => 'user',
'attribute' => 'name',
'model' => 'App\User',
],
]);
}
ProcessCrudController:
protected function setupListOperation()
{
CRUD::setFromDb();
// This table should be listing Order's query and that only have a process (already created custom_create_view)
// That's why i want to take Order's table and not making new custom_list_view
}
you don't have to make a new view, you just modify the query result using addClause ....
in your ProcessCrudController in setupListOperation() add your clause:
$this->crud->addClause('has','order');
assuming that the relation name in Process model that point to Process is "order"
i'm developing a web application with Yii2 framework, and i'm facing a problem right now. I want to display the data from a many-to-many relation in a gridview and be able to filter from those fields later on.
I've read the official documentation here, some stackoverflow post like this and other resources but can't seem to get it to work. I have 3 tables: actividad, plan_actividad and circulo_icare, actividad is related to plan_actividad and circulo_icare is also related to it (plan_actividad is the junction table). So i have defined the following relations in my Actividad model:
class Actividad extends \yii\db\ActiveRecord
{
....
public function getPlanActividad()
{
return $this->hasMany(PlanActividad::classname(), ['act_id' => 'act_id']);
}
public function getCirculo()
{
return $this->hasMany(CirculoIcare::classname(), ['cirica_id' => 'act_id'])->via('planActividad');
}
...
}
The in my view index.php i'm trying to show the values in a gridview like this:
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
// 'act_id',
['attribute' => 'Codigo Evento', 'value' => 'act_numorden'],
['attribute' => 'Nombre Evento', 'value' => 'act_nombre'],
['attribute' => 'Fecha Evento', 'value' => 'act_fecha'],
['attribute' => 'Locacion', 'value' => 'locacion.loc_nombre'],
[
'attribute' => 'Circulo',
'value' => 'circulo.cirica_nombre',
],
['attribute' => 'Circulo id',
'value' => 'planActividad.cirica_id',
],
// 'act_horaini',
// 'act_horafin',
// 'act_idencuesta',
// 'act_vigencia:boolean',
// 'loc_id',
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
The problem is, i can't get any values to show with the circulo relation, it always shows (not set). If i change hasMany in getPlanActividad() with hasOne() then it shows some values (only 2 of 11 it should, based on the cirica_id that exist on plan_actividad table) but these are not correct anyway. I know that i can filter for those fields later on in search view but i don't really understand why the relations doesn't work as i expected.
Any help would be greatly appreciated, let me know if more info is needed and thank you in advance.
Answering my own question (credits to softark from the yii official forums).
In order for the relation to work as expected, I had to change:
public function getCirculos()
{
return $this->hasMany(CirculoIcare::classname(), ['cirica_id' => 'act_id'])->via('planActividad');
}
to
public function getCirculos()
{
return $this->hasMany(CirculoIcare::classname(), ['cirica_id' => 'cirica_id'])->via('planActividad');
}
and use a callback function in the gridview to display the correct values, since a hasMany relation gives an array of models and not a single model. So I modified the gridview code to:
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
...
['attribute' => 'circulo',
'value' => function($model){
$items = [];
foreach($model->circulos as $circulo){
$items[] = $circulo->cirica_nombre;
}
return implode(', ', $items);
}],
...
['class' => 'yii\grid\ActionColumn'],
],
]); ?>
This gives the expected results. You can then apply filter by the relation fields easily by adapting the search model.
I add another table field in my view , but the search button disappeared , How can I retrieve this form button ?
SaleItems = And a table mysql database.
<?php
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'formatter' => ['class' => 'yii\i18n\Formatter','nullDisplay' => ''],
'columns' => [
['class' => 'yii\grid\SerialColumn'],
**[
'attribute' => 'Data',
'content' => function(SaleItems $model, $key, $index, $column) {
return date('d/m/Y', strtotime($model->sale->date));
},
'header' => 'DATA'
],**
]); ?>
</div>
The search field disappears because in not setted properly in searchModel ..
for this you must extend the related modelSeacrh adding the relation with the related model and the filter for the field you need ..
for this you must set in the base mode, the relation
public function getSale()
{
return $this->hasOne(Sale::className(), ['id' => 'sale_id']);
}
/* Getter for sale data */
public function getSaleData() {
return $this->sale->data;
}
then setting up the search model declaring
/* your calculated attribute */
public $date;
/* setup rules */
public function rules() {
return [
/* your other rules */
[['data'], 'safe']
];
}
and extending
public function search($params) {
adding proper sort, for data
$dataProvider->setSort([
'attributes' => [
.....
'data' => [
'asc' => ['tbl_sale.data' => SORT_ASC],
'desc' => ['tbl_sale.data' => SORT_DESC],
'label' => 'Data'
]
]
]);
proper relation
if (!($this->load($params) && $this->validate())) {
/**
* The following line will allow eager loading with country data
* to enable sorting by country on initial loading of the grid.
*/
$query->joinWith(['sale']);
return $dataProvider;
}
and proper filter condition
// filter by sale data
$query->joinWith(['sale' => function ($q) {
$q->where('sale.data = ' . $this->data . ' ');
}]);
Once you do al this the searchModel contain the information for filter and the search field is showed in gridview
What in this answer is just a list of suggestion
you can find detailed tutorial in this doc (see the scenario 2 and adapt to your need)
http://www.yiiframework.com/wiki/621/filter-sort-by-calculated-related-fields-in-gridview-yii-2-0/
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]);
},
],