Yii2-advanced : ArrayDataProvider - php

I want to use ArrayDataProvider with the following code of siteController. I wrote the following code but it doesn't work.
Here is my actionIndex :
public function actionIndex()
{
$query = new \yii\db\Query;
$query->select('*')->from('business_main_categories');
$query->createCommand();
$dataProviders = [];
foreach ($query as $category) {
$dataProviders[] = new ArrayDataProvider([
'allModels' => $category,
'sort' => false,
'pagination' => false,
]);
}
return $this->render('index', [
'dataProvider' => $dataProviders,
]);
}
And want it to iterate in gridView. So, I wrote the following code (I don't know whether it's correct or not) :
Here is my index.php :
<?php
$dataProviders[] = 'dataProvider';
foreach ($dataProviders as $dataProvider) {
echo GridView::widget([
'dataProvider' => $dataProvider,
'summary' => '',
'columns' => [
[
'attribute' => 'bmc_image',
'format' => 'html',
'label' => '',
'value' => function ($data) {
return Html::img($data['bmc_image'],
['width' => '210px', 'height' => '190px']);
},
],
]
]);
}
?>

Controller
public function actionIndex()
{
$query = new \yii\db\Query;
$dataProvider = new ArrayDataProvider([
'allModels' =>$query->from('business_main_categories')->all(),
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
Index
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute' => 'bmc_image',
'format' => 'html',
'value' => function ($data) {
return Html::img($data['bmc_image'],['width' => '210px', 'height' => '190px']);
},
],
],
]); ?>

I solved my problem without using gridview. As follows -
My SiteController -
public function actionIndex()
{
$searchModel = new BusinessMainCategoriesSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->pagination->pageSize = $dataProvider->getTotalCount(); //-1 : disable
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
using this code I get all records in dataProvider from my db.
(Note that, I'm using ActiveDataProvider in my 'BusinessMainCategoriesSearch' model)
And, my index.php is -
<?php
$m = $dataProvider->getModels();
foreach ($m as $dp) {
echo "<img src = '".$dp['bmc_image']."' />";
echo '<center><font color = "white">'.$dp['bmc_name'].'<font/></center>';
}
?>
It worked great for me & it's a easiest way to do so.

Related

Updating forms values is not working yii2

I have default forms which were generated by crud. I need to update message column.
My View site/index.php
<div class="notifications-events-index">
<?= Html::encode($this->title) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'summary' => false,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'date_at',
'type',
'event_id',
[
'attribute' => 'Message',
'filter' => true,
'format' => 'raw',
'value' => function ($model) {
$form = ActiveForm::begin([
'action' => Yii::$app->urlManager->createUrl(['site/update', 'id' => $model->id])
]);
return $this->render('_msg', [
'model' => $model,
'form' => $form,
]);
},
]
],
]); ?>
<?php ActiveForm::end(); ?>
My updateAction in SiteController
public function actionUpdate($id)
{
$model = $this->findModel($id);
$dataProvider = new ActiveDataProvider([
'query' => NotificationsEvents::find()->orderBy('date_at'),
]);
if ($model->load(Yii::$app->request->post())) {
$model->save(false);
return $this->redirect(['index']);
}
return $this->render('index', [
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
findModel is working. When I save my updating values they are not updating. Any ideas?
Possible Reason to not updating the records:
Check validation , there may be a chance some validation is applying.
Check you attribute available in safe in your model .
Debug Your POST data. There may be a chance your post data is not posted .
If you still not able to solve it please post you model as well .

Yii2: display some records at the top of GridView widget

In Yii2 app I have model Document which can belong to user. Belonging is set with owner_id field.
In view I display list of Documents using GridView widget. Default sort is by document_id.
Every user sees all documents (event if specific document doesn't belong to him).
But I need to display documents which belongs to current logged in user at the top of GridView. How can I do this?
I suppose I should make some changes to Document::search() method by can't find out what excactly I should do.
Here is my controller action:
public function actionIndex()
{
$modelFullName = $this->modelFullName;
$model = new $modelFullName();
$dataProvider = $model->search(Yii::$app->request->queryParams);
return $this->render(
'index',
[
'model' => $model,
'dataProvider' => $dataProvider,
]
);
}
Part of view:
echo GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $model,
'columns' => [
[
'attribute' => 'document_id',
],
[
'attribute' => 'status',
'format' => 'raw',
'value' => function($model) {
return $model->statusString;
},
],
[
'attribute' => 'title',
],
[
'attribute' => 'date_created'
],
[
'attribute' => 'client_id',
'value' => function($model) {
return $model->client ? $model->client->title : '';
},
'filter' => ArrayHelper::map(Clients::find()->all(), 'client_id', 'title')
],
[
'attribute' => 'project_id',
'value' => function($model) {
return $model->project ? $model->project->title : '';
},
'filter' => ArrayHelper::map(Projects::find()->all(), 'project_id', 'title')
],
[
'class' => yii\grid\ActionColumn::className(),
'template' => '{view} {delete}',
'buttons' => [
'view' => function ($url, $model) {
return $this->context->getBtn('view', $model);
},
'delete' => function ($url, $model) {
if (Yii::$app->user->can('deletePrsSum')) {
return $this->context->getBtn('delete', $model);
}
},
],
'visibleButtons' => [
'update' => Yii::$app->user->can('updateDocument'),
'delete' => Yii::$app->user->can('deleteDocument'),
]
],
],
]);
Current Document::search() implementation:
public function search($params)
{
$query = self::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
'sort' => [
'defaultOrder' => ['document_id' => SORT_ASC]
]
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
if ($this->client_id) {
$query->andFilterWhere([
'client_id' => $this->client_id,
]);
}
if ($this->project_id) {
$query->andFilterWhere([
'project_id' => $this->project_id,
]);
}
return $dataProvider;
}
UPDATE
So how I managed to do this:
public function search($params)
{
$userId = Yii::$app->user->identity->user_id;
$query = self::find()->select(
"*, IF(owner_id={$userId},(0),(1)) as sort_order"
)->orderBy([
'sort_order' => SORT_ASC,
'document_id' => SORT_ASC
]);
//further code...
Add a filter in your search function to filter with the id of the logged in person/user:
$query->andFilterWhere(['owner_id' => Yii::$app->user->identity->id]);

ActionColumn Yii2, $key always return 0 based from searchModel

Basically, I want to make a CRUD page which is the dataProvider that came from Query class.
So, In controller :
public function actionIndex(){
$searchModel = new RequestBisaApproveSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Then in RequestBisaApproveSearch(); which is the dataProvider :
public function search($params)
{
$karyawan = Karyawan::findOne(['id' => \Yii::$app->user->identity->karyawan_id]);
$dataKaryawan = $karyawan->linkKaryawanPerusahaanBranchDepartementJabatans;
$branches = [];
$perusahaans = [];
$departements = [];
$jabatans = [];
foreach ($dataKaryawan as $data) :
array_push($branches, $data['branch_id']);
array_push($perusahaans, $data['perusahaan_id']);
array_push($departements, $data['departement_id']);
array_push($jabatans, $data['jabatan_id']);
endforeach;
$query = (new Query())
->select("re.id as id, kar.first_name, kar.last_name, re.status, re.header, re.tanggal_permintaan")
->from('ytresnamuda_it.request re')
->join('LEFT JOIN', 'ytresnamuda_hrd.karyawan kar', 're.karyawan_id = kar.id')
->join('LEFT JOIN', 'ytresnamuda_hrd.link_karyawan_perusahaan_branch_departement_jabatan li', 'kar.id = li.karyawan_id');
$query->where(['IN','li.branch_id', $branches]);
$query->andWhere(['IN','li.perusahaan_id', $perusahaans]);
$query->andWhere(['IN','li.departement_id', $departements]);
$query->andWhere(['<','li.jabatan_id', max($jabatans)]);
$query->andWhere(['!=','li.karyawan_id', $karyawan->id ]);
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
return $dataProvider;
The problem is, when to make a actionColumn.
Yii2 have a function to createUrl in actionColumn like this:
[
'class' => 'kartik\grid\ActionColumn',
'dropdown' => false,
'width' => '150px',
'template' => '{approve} {print-request}',
'vAlign' => 'top',
'urlCreator' => function ($action, $model, $key, $index) {
return Url::to([$action, 'id' => $key]);
},
'buttons' => [
'approve' => function ($url, $model, $key) {
return Html::a( $key, Url::to(['request-bisa-approve/approve', 'id' => $key]),
[
'class' => 'btn btn-sm btn-primary btn-gii-action-customized fa fa-thumbs-o-up',
'role' => 'modal-remote',
'data-toogle' => 'tooltip',
'title' => 'Reminder IT'
]);
},
],
],
If you can see in :
'urlCreator' => function ($action, $model, $key, $index) {
return Url::to([$action, 'id' => $key]);
},
id is $key.So, I check it with another column,
[
'class' => '\kartik\grid\DataColumn',
'width' => '30px',
'attribute' => 'id',
'vAlign' => 'top',
],
The result is : id is valid integer. But $key always 0.
Weird, but if someone have clue, it so much appreciate.

Checkbox column not Working in yii2 gridview with Modal

I have a gridview . It displays the departments available in a college.
When I click the row it populate the modal and Its shows the lecturer available for the selected department in kartik gridview .
In that I am using the kartik/grid/CheckboxColumn.
But when I click the Checkbox and get the selected rows through javacript, It doesn't return primary key associated with the record.
If I execute the gridview without modal , then it works fine
$this->registerJs("
$('#lect-logout').click(function() {
var key = $('#w0-container').yiiGridView('getSelectedRows');
alert(key);
$.post(
'?r=lec-logout/logout',
{
id: $('#w0').yiiGridView('getSelectedRows'),
},
function (data) {
alert("ok");
}
);
});
");
How to use that checkbox with the modal. Even I click select all option in checkbox. It doesn't select all the rows.
Controller Code
public function actionIndex()
{
$searchModel = new CollegeSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [ 'searchModel' => $searchModel, 'dataProvider' => $dataProvider]);
}
public function actionLecture()
{
$model = new Accounts();
if ($model->load(Yii::$app->request->post())) {
return $this->redirect(['index']);
}
else{
$searchModel = new LectureSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->renderAjax('lecture', ['searchModel' => $searchModel,'dataProvider' => $dataProvider]);
}
}
View CODE
index.php
<?= GridView::widget([
'dataProvider' => $dataProvider,
'rowOptions' => function($model, $key, $index, $grid) {
return ['id' => $model['account_id'], 'onclick' => 'getrow(this.id)'];
},
'columns' => [
'displayname',
],
]); ?>
<?php Modal::begin([
'id' => 'show-agents-modal',
'size' => 'modal-lg',
'header' => '<h4 class="modal-title">View</h4>',
]);
Modal::end(); ?>
Lecture.php
<div class="pull-right">
<?= Html::Button('Logout',['class'=>'btn btn-primary','id'=>'lect- logout']); ?>
</div>
<br>
<?= GridView::widget([
'dataProvider' => $dataProvider,
// 'filterModel' => $searchModel,
'columns' => [
'first_name,
['class' => 'kartik\grid\CheckboxColumn'],
],
]); ?>
If you want to use yii\grid\CheckboxColumn then try this :
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'class' => 'yii\grid\CheckboxColumn',
'checkboxOptions' => function($model, $key, $index, $column) {
return ['value' => $model->your_id];
},
],
.
.
])?>

Yii2 Pjax Delete not working

I am trying to make an Ajax GridView using Pjax with delete button. Deleting goes with no Ajax. I am new to Yii2 so any help would be appreciated. Thank you.
index.php
<?php Pjax::begin(['id' => 'countries']) ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
'id',
'title',
['class' => 'yii\grid\ActionColumn',
'buttons' => [
'delete' => function ($url, $model, $key) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('yii', 'Delete'),
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'data-method' => 'post',
]);
},
]
],
],
]); ?>
<?php Pjax::end() ?>
Controller
public function actionDelete($id)
{
$model = new Category();
$this->findModel($id)->delete();
$dataProvider = new ActiveDataProvider([
'query' => Category::find(),
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
This is public function actionIndex() in the Controller
public function actionIndex()
{
$model = new Category();
$dataProvider = new ActiveDataProvider([
'query' => Category::find(),
]);
if ($model->load(Yii::$app->request->post()) && $model->save())
{
$model = new Category();
}
return $this->render('index', [
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
data-method and data-confirm don't let you create ajax request via pjax, you should implements your own confirmation dialog and drop POST verb filter, or you can implements your own ajax plugin with confirmation dialog and specifying http method.
Also, i think, there must be way to extend pjax plugin by confirmation dialog, but Yii2 don't provide this by default.
first of all remove 'data-confirm' and 'data-method' => 'post'. pjax not going to work.
If you want to implement a confirm box with action button, here is what I would do in my view index.php file ..
<?php Pjax::begin(['id' => 'pjax-container']);
echo GridView::widget([
'test' => function ($url, $dataProvider) {
return Html::a('Test',
['/site/test'],
['title'=>'Test',
'onclick' => "if (confirm('ok?')) {
$.ajax('/site/test', {
type: 'POST'
}).done(function(data) {
$.pjax.reload({container: '#pjax-container'});
});
}
return false;
",
]);
},
])
Pjax::end();
?>
and in my controller
public function actionTest()
{
if (!Yii::$app->request->isAjax) {
return $this->redirect(['index']);
}
}
This way you would have confirmation etc. as well. If you want you may use other third party bootstrap confirmation etc. and will work fine.
<?php Pjax::begin(['id' => 'model-grid']);
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
//...
[
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete}',
'contentOptions' => ['class' => 'action-column'],
'buttons' => [
'delete' => function ($url, $model, $key) {
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => 'Delete',
'data-pjax' => '#model-grid',
]);
},
],
],
],
]);
Pjax::end(); ?>
In controller
public function actionDelete($id)
{
$this->findModel($id)->delete();
$searchModel = new ModelSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
Please try modify actionDelete()
public function actionDelete($id)
{
$this->findModel($id)->delete();
return \yii\web\Response::redirect(['index'] , 302 , false);
// return $this->redirect(['index']);
}
because Controller->redirect() can not disable ajaxCheck , you need use Response to do this.
I have create the same issue in https://github.com/yiisoft/yii2/issues/11058.
Can use like this:
in view:
'delete' => function ($url, $model, $key) {
$options = [
'title' => Yii::t('common', 'delete'),
'aria-label' => Yii::t('common', 'delete'),
'data-pjax' => 'w0',//id
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'data-method' => 'post',
'class' => 'btn btn-xs btn-danger'
];
return Html:: a('<i class="fa fa-fw fa-trash"></i>', [
'delete',
'id' => $model -> id
], $options);
}
in controller:
$this -> findModel($id) -> delete ();
$searchModel = new AdminSearch();
//get the referer url
$url = Yii::$app -> request -> referrer;
$arr = parse_url($url, PHP_URL_QUERY);
parse_str($arr, $output);//get the $_GET array
$dataProvider = $searchModel -> search($output);
return $this -> render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
First add Pjax::end(); at end of the gridview
then specify:
'delete' => function ($url, $model, $key)
{
return Html::a('<span class="glyphicon glyphicon-trash"></span>', $url, [
'title' => Yii::t('yii', 'Delete'),
'data-confirm' => Yii::t('yii', 'Are you sure you want to delete this item?'),
'data-method' => 'post',
]);
},
Note that you don't need to specify 'data-pjax' => '0' because it disables the pjax link.
For more details check this link
Your controller should be:
public function actionDelete($id)
{
$this->findModel($id)->delete();
return $this->redirect(['index']);
}
Don't set data-method and data-confirm because Pjax not supported that.
After removing both still not workign,yes because of below code of your controler does not allow Pjax get Request.
return [
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'], // **remove this**
],
],
];
You need to use Pjax Post Method
Apply this in Your Pjax
'clientOptions' => ['method' => 'POST']

Categories