I need help with search model for ArrayDataProvider. Let's say i have an array:
$cities = [
['city' => "Chicago", 'year' => 1984],
['city' => "Washington", 'year' => 2001],
['city' => Manchester", 'year' => 1997],
//and so on...
];
I create an ArrayDataProvider:
$provider = new \yii\data\ArrayDataProvider([
'allModels' => $catalog,
'sort' => [
'attributes' => ['city', 'year'],
],
]);
Then I create a GridView:
echo \yii\grid\GridView::widget([
'dataProvider' => $provider,
'filterModel' => (new LibrarySearchModel()),
'columns' => $columns,
'showHeader' => true,
'summary' => false,
]);
All works fine, but i need a filtering in GridView. There is no option to use ActiveDataProvider and I cant find any tutorial how to filter a data in ArrayDataProvider. Can someone help me with code for filter model or recomend the docs for my case?
This is example of how to use ArrayDataProvider with filters in the GridView.
public function actionExample()
{
$data = new \app\models\Data();
$provider = $data->search(Yii::$app->request->get());
return $this->render('example', [
'provider' => $provider,
'filter' => $data,
]);
}
This is classic Yii 2 approach to the GridView so I will not explain it (you can find details in the Guide linked above).
<?php
echo \yii\grid\GridView::widget([
'dataProvider' => $provider,
'filterModel' => $filter,
'columns' => [
'name',
'code',
],
]);
Again, nothing different from the ActiveDataProvider approach. As you can see here we are expecting two columns: name
and code
- these will be defined below.
Data
model.Prepare the model that will handle the data source. Explanation is given in the comments.
<?php
namespace app\models;
use yii\base\Model;
/**
* Our data model extends yii\base\Model class so we can get easy to use and yet
* powerful Yii 2 validation mechanism.
*/
class Data extends Model
{
/**
* We plan to get two columns in our grid that can be filtered.
* Add more if required. You don't have to add all of them.
*/
public $name;
public $code;
/**
* Here we can define validation rules for each filtered column.
* See http://www.yiiframework.com/doc-2.0/guide-input-validation.html
* for more information about validation.
*/
public function rules()
{
return [
[['name', 'code'], 'string'],
// our columns are just simple string, nothing fancy
];
}
/**
* In this example we keep this special property to know if columns should be
* filtered or not. See search() method below.
*/
private $_filtered = false;
/**
* This method returns ArrayDataProvider.
* Filtered and sorted if required.
*/
public function search($params)
{
/**
* $params is the array of GET parameters passed in the actionExample().
* These are being loaded and validated.
* If validation is successful _filtered property is set to true to prepare
* data source. If not - data source is displayed without any filtering.
*/
if ($this->load($params) && $this->validate()) {
$this->_filtered = true;
}
return new \yii\data\ArrayDataProvider([
// ArrayDataProvider here takes the actual data source
'allModels' => $this->getData(),
'sort' => [
// we want our columns to be sortable:
'attributes' => ['name', 'code'],
],
]);
}
/**
* Here we are preparing the data source and applying the filters
* if _filtered property is set to true.
*/
protected function getData()
{
$data = [
['name' => 'Paul', 'code' => 'abc'],
['name' => 'John', 'code' => 'ade'],
['name' => 'Rick', 'code' => 'dbn'],
];
if ($this->_filtered) {
$data = array_filter($data, function ($value) {
$conditions = [true];
if (!empty($this->name)) {
$conditions[] = strpos($value['name'], $this->name) !== false;
}
if (!empty($this->code)) {
$conditions[] = strpos($value['code'], $this->code) !== false;
}
return array_product($conditions);
});
}
return $data;
}
}
The filtering in this example is handled by the array_filter function. Both columns are filtered "database LIKE"-style - if column value contains the searched string the data
array row is not removed from the source.
To make it work like and
conditions in ActiveDataProvider we put boolean result of every column check in the $conditions
array and return product of that array in array_filter
.
array_product($conditions)
is equivalent of writing $conditions[0] && $conditions[1] && $conditions[2] && ...
This all results in the filterable and sortable GridView widget with two columns.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With