I need to set custom data-attribute to the ListView elements. As example I try to get current DataProvider model id. But I still view error "htmlspecialchars() expects parameter 1 to be string, object given". Please check my code and halp me - how I should get this ID?
<?= ListView::widget([
'dataProvider' => $photoProvider,
'id' => 'photo-list',
'itemView' => '_photoListItem',
'viewParams' => [
'fullView' => true,
],
'options' => [
'tag' => 'ul',
'class' => 'list-view'
],
'itemOptions' => [
'tag' => 'li',
'class' => 'item',
'data' =>[
'test' => function ($model, $key, $index, $widget) {
return Html::encode($model->id);
}
]
],
'pager' => [
'class' => ScrollPager::className(),
'container' => '#photo-list',
'item' => '.item',
'triggerText' => '<div class="btn more">Load More</div>',
'noneLeftText' => '',
'triggerOffset' => 2,
'negativeMargin' => 200
],
'layout' => "{items}\n{pager}",
]);
?>
This is not possible in the ListView, according to the doc:
'data' => [
'test' => function ($model, $key, $index, $widget) {
return Html::encode($model->id);
}
]
You cannot use a function here. Only static values are allowed.
Alternatively, you can provide those attributes in tags of your _photoListItem view file.
Related
i'm got stuck for 2 days, i got confused how to render column usind yajra/laravel-datatable
i'm using postgre as database, and yajra/laravel-datatables as package.
i have query builder like this
$data = DB::select("SELECT * FROM get_list_count_amount_transaction('chat', 'done', '2019-03-01', '2021-12-31' )")[0];
which generates a value of object : (i use var_dump() to see the value)
{ ["list_data"]=> string(2171)
"[{"id":"44649ccd-9195-4964-b48c-ed2098077dc5","kd_join":1,"status":"done","booking_date":"2021-04-18","transaction_type":"chat","price":4000.00,"date_create":"2021-04-18T19:56:57"},
{"id":"e500d2c1-99ae-4436-8ecc-8073f4f05bba","kd_join":1,"status":"done","booking_date":"2021-03-20","transaction_type":"chat","price":10000.00,"date_create":"2021-03-19T21:41:41"}
]"
["count_transaction"]=> int(12)
["total_amount_transaction"]=> string(9) "160500.00"
}
i'm confused, how to render list_data into a table using datatble
this is my html builder function :
public function html()
{
return $this->builder()
->columns($this->getColumns())
->minifiedAjax()
->addAction(['width' => '200px'])
->addColumnBefore([
'defaultContent' => '',
'data' => 'DT_Row_Index',
'name' => 'DT_Row_Index',
'title' => 'No',
'render' => function () {
return 'function(data,type,fullData,meta){return meta.settings._iDisplayStart+meta.row+1;}';
},
'orderable' => false,
'searchable' => false,
'exportable' => false,
'printable' => true,
'footer' => '',
]);
}
protected function getColumns()
{
return [
['data' => 'transaction_type', 'name' => 'transaction_type', 'title' => 'Tipe Transaksi', 'orderable' => false],
['data' => 'status', 'name' => 'status', 'title' => 'Status', 'orderable' => false],
['data' => 'booking_date', 'name' => 'booking_date', 'title' => 'Tanggal Booking', 'orderable' => false],
['data' => 'price', 'name' => 'price', 'title' => 'Jumlah', 'orderable' => false],
];
}
}
Just grab the list_data, use json_decode and laravel collection to make your needed structure. Try to use map, filter, mapWithKeys or whatever suitable.
For Instance:
collect(json_decode($listData))->mapWithKeys(function($item)){
//
}
I'm trying to create summary row for my GridView which sums my quantity for current page and for all records seperately.
<?= GridView::widget([
'dataProvider' => $dataProvider,
'layout' => "{summary}\n{items}\n<div align='right'>{pager}</div>",
//'filterModel' => $searchModel,
'showPageSummary' => true,
'pageSummaryFunc' => GridView::F_SUM,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'class' => DataColumn::className(),
'attribute' => 'updated_at',
'format' => 'raw',
'value' => function ($model, $key, $index, $column){
return date('Y-m-d', $model->updated_at);
},
],
[
'label' => 'Ilość',
'attribute'=>'quantity',
'pageSummary' => true,
'value'=> function ($model, $key, $index, $column) {
return ($model->quantity) ? $model->quantity : '';
},
],
],
]); ?>
At the end i want to export sum for all records to my excel sheet at the bottom of my gridColumns. My export widget looks like:
$dataProviderAll->setSort([
'defaultOrder' => ['updated_at' => SORT_ASC]
]);
echo ExportMenu::widget([
'container' => ['class' => 'btn-group pull-right', 'role' => 'group'],
'dataProvider' => $dataProviderAll,
'columns' => $gridColumns,
'filename' => date('Y-m-d') . '_raport',
'target' => ExportMenu::TARGET_SELF,
'showConfirmAlert' => false,
'showColumnSelector' => false,
'fontAwesome' => true,
'dropdownOptions' => [
'label' => 'Eksportuj dane',
'class' => 'btn btn-primary btn-md'
],
'exportConfig' => [
ExportMenu::FORMAT_HTML => null,
ExportMenu::FORMAT_TEXT => null,
ExportMenu::FORMAT_EXCEL => null,
ExportMenu::FORMAT_PDF => null
]
]);
?>
All columns of model are already exported, but i need to add summary row for some of them into created excel file.
Im getting now error like this: Setting unknown property: kartik\grid\GridView::pageSummaryFunc
Does someone know how can I get this result?
I have fixed part where I wanted to get sum per page by replacing class column from yii to kartik. –
I have a moneyFieldset with 2 fields, amount and currency.
class MoneyFieldset ...
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->setHydrator(...);
$this->add(array(
'name' => 'currency',
'type' => 'select',
'options' => array(
'value_options' => \Core\Service\Money::getAvailableCurrencies(true),
),
'attributes' => array(
'value' => \Core\Service\Money::DEFAULT_CURRENCY,
),
));
$this->add(array(
'name' => 'amount',
'type' => 'text',
));
}
}
public function getInputFilterSpecification()
{
$default = [
'amount' => [
'required' => false,
'allow_empty' => true,
'filters' => [
['name' => AmountFilter::class]
],
'validators' => [
]
],
'currency' => [
'required' => false,
'allow_empty' => true,
'filters' => [
['name' => StringToUpper::class]
],
'validators' => [
]
]
];
return \Zend\Stdlib\ArrayUtils::merge($default, $this->filterSpec, true);
}
I'm using moneyFieldset in my other fieldsets like this:
// Price Field
$this->add(array(
'name' => 'price',
'type' => 'form.fieldset.moneyFieldset',
'attributes' => array(
'required' => true,
'invalidText' => 'Please type an amount'
),
'options' => array(
...
),
));
When I set filter like this:
function getInputFilterSpecification()
{
'price' => [
'required' => true,
'allow_empty' => false,
],
}
It's not working because price has 2 fields, so how can I say price[amount] and price[curreny] is required?
You can provide the input specifications for the nested fieldset (within the context of the form) using the following array structure.
public function getInputFilterSpecification()
{
return [
// ...
'price' => [
'type' => 'Zend\InputFilter\InputFilter',
'amount' => [
'required' => true,
],
'currency' => [
'required' => true,
]
],
//...
];
}
If you are dynamically modifying the values of the input filter it might be worth considering creating the validator using a service factory class and then attaching it to a form using the object API rather than arrays.
As I said in #AlexP's comment, a field, or a group of field declared as Required like this :
function getInputFilterSpecification()
{
'price' => [
'required' => true,
'allow_empty' => false,
],
}
Not means that it will be print an html like this :
<input type="text" required="required"/>
It just check when you'll do $form->isValid() if your fields are empty and required or other checks.
To achieve that, you just have to set in attributes that you want to require those fields. As you already did. Attributes can add, same as class attribute, html code to an input.
P.S : AlexP's answer is the best answer I just give more info about it.
have relation
model Shop.php
public function getShopAddr()
{
return $this->hasOne(SprShopAddr::className(), ['id' => 'shop_addr_id']);
}
model SprShopAddr.php
public function getDivision()
{
return $this->hasOne(SprDivision::className(), ['id' => 'division_id']);
}
model SprDivision.php
public function getShopAddrs()
{
return $this->hasMany(SprShopAddr::className(), ['division_id' => 'id']);
}
view index.php
<?= GridView::widget([
'dataProvider' => $dataProvider,
//'filterModel' => $searchModel,
'summary' =>false,
'columns' => [
'location_code',
[
'label' => 'Дивизион',
'attribute' => 'division_id',
'value' => 'shopAddr.division.division'
],
['class' => 'yii\grid\ActionColumn', 'template' => '{update}{delete}'],
]
]); ?>
sort on gridview for field shopAddr.division.division not working. How to fix it?
for related model you must configure properly the setSort function of the dataProvider
You can find the right information in this tutorial.
The most important part is that you must define the $dataProvider->setSor(...) function in yourModelSearch like this
$dataProvider->setSort([
'attributes' => [
'yuorRelatedFieldName' => [
'asc' => [ $tableRelated . '.yourField' => SORT_ASC ],
'desc' => [ $tableRelated . '.yourField' => SORT_DESC ],
'label' => 'yuorLabel'
],
],
'defaultOrder' => ['yuorDefaultOrderField' => SORT_ASC],
]);
I am trying to pass $arr_judete_v2 as a param to a callback function in a gridview and it does not work;
$model['county_id'] returns a number
$arr_judete_v2[1]['nume'] returns a name
my issue:
[
'attribute' => 'county_id',
'label' => Yii::t('diverse', 'Judet'),
'content' => function($model, $arr_judete_v2) {
return $arr_judete_v2[$model['county_id']]['nume'];
},
],
the entire gridview
<?php
echo GridView::widget([
'layout' => "{items}",
'dataProvider' => $dataProvider,
'columns' => [
'id',
[
'attribute' => 'nume',
'label' => Yii::t('companie', 'nume'),
],
'cui',
'email',
[
'attribute' => 'county_id',
'label' => Yii::t('diverse', 'Judet'),
'content' => function($model, $arr_judete_v2) {
return $arr_judete_v2[$model['county_id']]['nume'];
},
],
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'buttons' => [
'update' => function ($url, $model) {
return Html::a('<span class="glyphicon glyphicon-pencil"></span>', ['update', 'id' => $model['id']], [
'title' => Yii::t('yii', 'Update'),
'data-pjax' => '0',
]);
}
]
],
],
]);
From the source code for \Yii\grid\Column
#var callable This is a callable that will be used to generated the content of each cell.
The signature of the function should be the following: function ($model, $key, $index, $column)
As Mihai has correctly pointed out you can use use() to include variables into the function's scope as follows:
"content" => function($model, $key, $index, $column) use ($arr_judete_v2) {
return $arr_judete_v2[$model['county_id']]['nume'];
}
Please note that the variables are copied into the function and as such any changes will not affect the variable outside of the function. A better explanation of this is given in this answer.
Use use (), see how the function is defined for the value of the column.
$invoice_status_data = array('' => 'Select a status') + ArrayHelper::map(InvoiceStatus::find()->asArray()->all(), 'id', 'name');
........................
'columns' => [
........................
[
'attribute'=>'Contact.name',
'format'=>'raw',
'value'=>function ($model, $key, $index, $widget) use ($invoice_status_data) {
.............................
$content .=
Html::dropDownList('dropdown'. $model->id, '', $invoice_status_data, [
'class' => 'form-control',
'onchange' => 'javascript: myInvoice.change($(this));',
'data-href' => Url::toRoute(['invoice/change-status', "Invoice_id"=>$model->id])]);
return $content;
},
],