Yii2 renderPartial view in Layout - yii2

I'm trying to render a view to my layout on yii2 but I get an error
PHP Notice – yii\base\ErrorException
Undefined variable: dataProvider
I create a controller category with function
public function Wdgcategory()
{
$dataProvider = new ActiveDataProvider([
'query' => Category::find(),
]);
return $this->renderPartial('wdgCategory', [
'dataProvider' => $dataProvider,
]);
}
And in my view I create a view file in category/wdgCategory.php
<?php
use yii\helpers\Html;
use yii\widgets\ListView;
?>
<?= ListView::widget([
'dataProvider' => $dataProvider,
'itemOptions' => ['class' => 'item'],
'itemView' => function ($model, $key, $index, $widget) {
return '<li>'
.Html::a(Html::encode($model->category_name),
['view', 'id' => $model->category_id])
.'<li>';
},
]) ?>
and in layout I add this code
<ul>
<?= $this->render('/category/wdgCategory') ?>
</ul>
but I get error : Undefined variable: dataProvider

You have defined Wdgcategory() method but you're never using it. You're just trying to render view from layout without providing necessary data ($dataProvider).
In your case you should probably create widget for this list:
class CategoriesWidget extends \yii\base\Widget {
public function run() {
$dataProvider = new ActiveDataProvider([
'query' => Category::find(),
]);
return $this->render('categories', [
'dataProvider' => $dataProvider,
]);
}
}
And use it in your layout:
<?= CategoriesWidget::widget() ?>

Related

One search form to 3 Gridview in same page

Friends,
I have an INDEX page with 3 GRIDVIEW components (model Keys, model Products, model Indicators). And on that same page I have a search form with a dropdownlist (company).
I need to: When you select for example company 02 the 3 GRIDVIEW are filtered only company records 02.
_search.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
use kartik\date\DatePicker;
?>
<div class="ideas-search">
<?php $form = ActiveForm::begin([
'options' => [
'class' => 'form-inline',
],
'action' => ['index'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'pa')->dropdownList([..])?>
...
index.php
<?php echo $this->render('_search', ['model' => $searchBase]); ?>
<?php Pjax::begin(['id' => '1']) ?>
<?= GridView::widget([
'id' => 'grid1',
'dataProvider' => $dataProviderKey,
'columns' => [
...
],
]); ?>
<?php Pjax::end() ?>
<?php Pjax::begin(['id' => '2']) ?>
<?= GridView::widget([
'id' => 'grid2',
'dataProvider' => $dataProviderProduct,
'columns' => [
...
],
]); ?>
<?php Pjax::end() ?>
<?= GridView::widget([
'dataProvider' => $dataProviderIndicators,
'summary' => false,
'columns' => [
...
],
]); ?>
== UPDATE==
BaseController
public function actionIndex()
{
$searchBase = new BaseSearch();
$searchBase->pa = 0;
$searchBase->data = date("Y-m-d");
$dataProviderBase = $searchBase->search(Yii::$app->request->queryParams);
$searchMobilizadores = new MobilizadoresSearch();
$dataProviderMobilizadores = $searchMobilizadores->search(Yii::$app->request->queryParams);
$searchIndicadores = new IndicadoresSearch();
$dataProviderIndicadores = $searchIndicadores->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchBase' => $searchBase,
'dataProviderBase' => $dataProviderBase,
'searchMobilizadores' => $searchMobilizadores,
'dataProviderMobilizadores' => $dataProviderMobilizadores,
'searchIndicadores' => $searchIndicadores,
'dataProviderIndicadores' => $dataProviderIndicadores,
]);
}
dont forget define filterModel in your Gridview Widget
view file
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
1st Approach :
You may use a single model that extend from model that joint all 3 table and create a search model for it. If u insist on separating all 3 table in the view, you may just declare different column for each grid.
a tip to achieve this, you may create a view and use gii tool to generate view file.
the tricky part is that 1 model can only hold one table except you joint. But, by joining table, you may get extra rows that are not necessarily needed for lets say your $dataProviderKey grid.
2nd Approach :
manually check for params from Yii::$app->request->get() add filter for each $dataprovider.
controller file
if(isset($id = Yii::$app->request->get('company_id'))) {
$dataProviderKey->query->andFilterWhere(['company.id' => $id]);
$dataProviderProduct->query->andFilterWhere(['company.id' => $id]);
$dataProviderIndicators->query->andFilterWhere(['company.id' => $id]);
}
== UPDATE ==
to answer your update question, you may assign your base search attributes to the respective attributes from others searchModel like this :
public function actionIndex()
{
$searchBase = new BaseSearch();
$searchBase->pa = 0;
$searchBase->data = date("Y-m-d");
$dataProviderBase = $searchBase->search(Yii::$app->request->queryParams);
$searchMobilizadores = new MobilizadoresSearch();
$searchMobilizadores->company = $searchBase->company; -->add this
$dataProviderMobilizadores = $searchMobilizadores->search(Yii::$app->request->queryParams);
$searchIndicadores = new IndicadoresSearch();
$searchIndicadores->company = $searchBase->company; -->add this
$dataProviderIndicadores = $searchIndicadores->search(Yii::$app->request->queryParams);

Searching records for date fails

Following code should search records for date. But whatever I click,main branch in condition will be executed,so I will get outprinting:
choice_date is false
It will be searched for records which are <=department_created_date,but never for records >=department_created_date
Any ideas,how to fix this?
Here is my RadioList
<?php
use yii\helpers\Html;
use kartik\grid\GridView;
use yii\widgets\ActiveForm;
$this->title = Yii::t('app', 'Departments');
$this->params['breadcrumbs'][] = $this->title;
?>
<div class="departments-index">
<h1><?= Html::encode($this->title) ?></h1>
<?php
$form = ActiveForm::begin();
$model = new backend\models\DepartmentsSearch();
?><?= $form->field($model, 'choice_date')->radioList(array(0 => 'Before', 1 => 'After'))->label('Please, choose Datesearching!'); ?>
<p><?= Html::a(Yii::t('app', 'Create Departments'), ['create'], ['class' => 'btn btn-success']) ?></p>
<?=
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
['class' => 'yii\grid\SerialColumn'],
[
'attribute' => 'branches_branch_id',
'label' => Yii::t('app', 'Branch'),
'value' => function($model) {
if ($model->branches_branch_id) {
return $model->branchesBranch->branch_name;
} else {
return NULL;
}
},
'filterType' => GridView::FILTER_SELECT2,
'filter' => backend\models\Branches::getBranchList(),
'filterWidgetOptions' => [
'pluginOptions' => ['allowClear' => true],
],
'filterInputOptions' => ['placeholder' => 'Branch', 'id' => 'grid-Branch-search-rechtsart']
],
'branchesBranch.branch_name',
'department_name',
[
'attribute' => 'companies_company_id',
'label' => Yii::t('app', 'Company'),
'value' => function($model) {
if ($model->companies_company_id) {
return $model->companiesCompany->company_name;
} else {
return NULL;
}
},
'filterType' => GridView::FILTER_SELECT2,
'filter' => backend\models\Companies::getCompanyList(),
'filterWidgetOptions' => [
'pluginOptions' => ['allowClear' => true],
],
'filterInputOptions' => ['placeholder' => 'Company', 'id' => 'grid-Company-search-rechtsart']
],
'department_created_date',
['class' => 'yii\grid\ActionColumn'],
],
]);
?>
</div>
and here is my searching class:
<?php
namespace backend\models;
use Yii;
use yii\base\Model;
use yii\data\ActiveDataProvider;
use backend\models\Departments;
class DepartmentsSearch extends Departments {
public $choice_date;
public function rules() {
return [
[['department_id'], 'integer'],
[['choice_date'], 'boolean'],
[['department_name', 'department_created_date', 'department_status', 'companies_company_id', 'branches_branch_id'], 'safe'],
];
}
public function scenarios() {
return Model::scenarios();
}
public function search($params) {
$query = Departments::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate())
return $dataProvider;
/*
Whatever I click in RadioList,property will be 0,so I'll get setFlash->'choice_date is false'
*/
if ($this->choice_date == 0) {
Yii::$app->session->setFlash('If-branch is false', 'choce_date is false');
$query->andFilterWhere(['<=', 'department_created_date', $this->department_created_date]);
} else {
Yii::$app->session->setFlash('if-branch is true', 'choice_date is true');
$query->andFilterWhere(['>=', 'department_created_date', $this->department_created_date]);
}
$query->joinWith('companiesCompany');
$query->joinWith('branchesBranch');
$query->andFilterWhere(['like', 'department_name', $this->department_name])
->andFilterWhere(['like', 'companies.company_name', $this->companies_company_id])
->andFilterWhere(['like', 'branches.branch_name', $this->branches_branch_id])
->andFilterWhere(['like', 'department_status', $this->department_status]);
return $dataProvider;
}
}
Further ideas,how to fix this misery?
P.S.: For Bizley's help, here is an extraction of my controller:
class DepartmentsController extends Controller{
public function actionIndex(){
$searchModel = new DepartmentsSearch();
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->render('index', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
further methods are irrelevant,here. Why will property of date-record not be rendered in view?
}
Your $model in the view is RadioForm so the form sends this field as RadioForm[choice_date].
But you are expecting choice_date from DepartmentsSearch model and this field is left empty.
Remove the RadioForm model, it's totally unneeded. Use DepartmentsSearch model in the form view.
Update:
Since OP finally told that this is a GridView I can update my answer to suit him.
There is filterSelector property in GridView you can use - you can set there additional jQuery selectors that will be used for filtering.
Here is updated code with comments below:
<?php $form = ActiveForm::begin();
echo $form->field($searchModel /* 1 */, 'choice_date')->radioList([
0 => 'Before', 1 => 'After'
], ['itemOptions' => ['class' => 'choiceRadio' /* 2 */]])->label('Please, choose Datesearching!');
ActiveForm::end(); /* 3 */ ?>
<?= GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'filterSelector' => '.choiceRadio', /* 4 */
// ...
This is the $searchModel I was talking about. You don't need any other model here.
You can set here any CSS class you want, it's for filterSelector.
Don't forget to close form like you did in your original code.
This is the selector for the radio input. Mind the notation - . for CSS class, # for CSS id.

Yii2 - Search exact value and return result in detailview

I need to put on the page to search by protocol number, and display only one result when the entered protocol number is exactly the same. If possible the results to be shown, it is a DetailView
My model OccurrenceSearch:
public function searchprotocol($params)
{
$query = Occurrence::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
return $dataProvider;
}
$query->andFilterWhere([
'protocol' => $this->protocol,
]);
return $dataProvider;
}
}
My view search:
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="occurrence-search">
<?php $form = ActiveForm::begin([
'action' => ['search'],
'method' => 'get',
]); ?>
<?= $form->field($model, 'protocol') ?>
<div class="form-group">
<?= Html::submitButton('Search', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
My controller actionSearch() :
public function actionSearch()
{
$searchModel = new OccurrenceSearch();
$dataProvider = $searchModel->searchprotocol(Yii::$app->request->queryParams);
return $this->render('search', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
]);
}
The guest user can see only the record for its protocol number
The a detailView use model (and not dataProvider) for show the data instance ..
then in you controller you should obtain the model
public function actionSearch()
{
$searchModel = new OccurrenceSearch();
$dataProvider = $searchModel->searchprotocol(Yii::$app->request->queryParams);
$model = $dataProvider->query->one();
return $this->render('search', [
'searchModel' => $searchModel,
//'dataProvider' => $dataProvider,
'model' => $model,
]);
}
But in you view the code proposed don't show a detailView widget .. you should probably add
I decided to use the GRIDVIEW, and so changed the MymodelSearch
if (isset($_GET['AuthorSearch']) && !($this->load($params) && $this->validate())) {
return $dataProvider;
}

yii2 Pjax and GridView (pagination and post request)

As I understood when I click on the button "Confirm" pjax reload widget with new data,and started with firs paging page.
1)Is there any way to load new data but stay at current paging page?
2)Is there any way to sent 'id' parameter by POST method?
Controller
public function actionIndex()
{
$dataProvider = new ActiveDataProvider([
'query' => Orders::find()->with('orderServices.services','orderEmployees','user'),
'pagination' =>['pageSize' => 3],
]);
return $this->render('index', [
'dataProvider' => $dataProvider,
]);
}
In View
<?php \yii\widgets\Pjax::begin(); ?>
<?= GridView::widget([
// ... configuration here
'class' => 'yii\grid\ActionColumn',
'template' => '{update} {delete} {approve}'
,
'buttons' => [
'approve' => function ($url,$model,$key) {
if($model->status=='not confirm')
{
return Html::a('Confirm',Url::toRoute(['controller/action', 'id' => $model->id]));/// має бути Ajax
}
},
],
]
]);
<?php \yii\widgets\Pjax::end(); ?>
I don't if this could be useful for you but with :
Yii::$app->request->get('page')
You can obtain the current GET page in this way and use for your need

Could an ArrayDataProvider be used as an ActiveDataProvider?

I'm trying to use fill my listView using an ArrayDataProvider. However the dataProvider consists of Arrays, not objects. I ran into this problem because the category in the model is an id, where I need the name corresponding to that id from another table. Hence I created an Array where the id is the corresponding name.
private function getDataProvider()
{
return new ArrayDataProvider([
'allModels'=>$this->getFaqs(), // returns array of faqs
'sort'=>[
'attributes'=>['id','category','question','answer']],
'pagination'=>[
'pageSize'=>10,
],
]);
}
Here is my ListView widget
echo ListView::widget([
'dataProvider' => $dataProvider,
'itemView' => function($dataProvider, $key, $index, $widget)
{
return Html::a($dataProvider->question,
Url::toRoute(['faq/view', 'id' => $dataProvider->primaryKey]));
}
]);
It works, I use it like this
$dataProvider = new ArrayDataProvider([
'allModels' => [['name' => '0am - 6am'], ['name' => '6am - 9pm'], ['name' => '9am - 12pm'], ['name' => '12pm - 3pm'], ['name' => '3pm - 6pm']],
]);
<?= ListView::widget([
'dataProvider' => $dataProvider,
'layout' => "{items}",
'itemOptions' => ['class' => 'item', 'style' => 'margin-bottom: 5px;'],
'itemView' => function ($model, $key, $index, $widget) use ($transportRun) {
//return print_r($model, true);
return Html::a(Html::encode($model['name']), ['delivery/index', 'DeliverySearch' => ['transport_run' => $transportRun, 'timeslot' => $key]], ['class' => 'btn btn-lg btn-primary btn-block']);
},
]) ?>
ListView and GridView can use any class that implements yii\data\DataProviderInterface. You can take a look here http://www.yiiframework.com/doc-2.0/yii-data-dataproviderinterface.html to see who implements it, so you can use any of those classes on both ListView and GridView.
You should also be able to do a
'allModels'=>$this->faqs, // returns array of faqs