Search in ArrayDataProvider list in YII2 - php

I used below code to generate list in yii2
Controler code
$data = [['id'=>1, 'name'=>'name1'],
['id'=>2, 'name'=>'name2'],
['id'=>3, 'name'=>'name3'],
['id'=>4, 'name'=>'name4'],
['id'=>5, 'name'=>'name5'],
['id'=>6, 'name'=>'name6'],]
$provider = new ArrayDataProvider([
'allModels' => $data,
'pagination' => [
'pageSize' => 5,
],
'sort' => [
'attributes' => ['id', 'name'],
],
]);
$lists = $provider->getModels();
return $this->render('list', [
'provider' => $provider,
'lists' => $lists,
]);
View code
foreach($lists as $list){
.....
}
Pagination
\yii\widgets\LinkPager::widget([
'pagination'=>$provider->pagination,
]);
This code is working but i need search or filter option in this list
like name ='name2' search
I am new for yii2 framework Please suggest any suitable solution for this problem
Thanks

ArrayDataProvider implement sort only. You have 2 choice:
Fitler data before creating dataProvider
Extend ArrayDataProvider and implement filters.

Related

Two listView same page Yii2

I am trying to put two list views in the same page with Yii2 but whenever I change the page in one the second change too. Any suggestions? I searched everywhere and haven't found any similar issues although I think it's very basic. Any help?
In controller you may pass two data provider for the two list views this may help
you to solve this
public function actionView($id)
{
$model = $this->findModel($id);
$reportsToUserDataProvider = new ActiveDataProvider([
'query' => $model->parent()
]);
$reporteeDataProvider = new ActiveDataProvider([
'query' => $model->children(),
'pagination' => false,
]);
Yii::$app->session->setFlash('alert', [
'options' => ['class' => 'alert-success'],
'body' => 'Your Reportees has been updated successfully'
]);
}
return $this->render('view', [
'model' => $model,
'reportsToUserDataProvider' => $reportsToUserDataProvider,
'reporteeDataProvider' => $reporteeDataProvider,
]);
}

Saving multiple records in a laravel eloquent create

I'm trying to save multiple records via
AppSettings::create(
[
'name' => 'mail_host',
'type' => $emailsettingstype->id,
'value' => '',
],
[
'name' => 'mail_port',
'type' => $emailsettingstype->id,
'value' => '',
],
[
'name' => 'mail_username',
'type' => $emailsettingstype->id,
'value' => '',
],
);
But from the above, only the first array is getting created. Where am i going wrong? Any help is appreciated.
I think this should do
AppSettings::createMany([
[
'name'=>'mail_host',
'type'=>$emailsettingstype->id,
'value'=>'',
],
[
'name'=>'mail_port',
'type'=>$emailsettingstype->id,
'value'=>'',
],
[
'name'=>'mail_username',
'type'=>$emailsettingstype->id,
'value'=>'',
],
]);
Make sure you're passing an array of arrays, not a params of array.
UPDATE, you can use Model::insert() although according to what I've read, that method doesn't create/update the timestamps.
You can just use Eloquent::insert() link as below:
AppSettings::insert([
[
'name'=>'mail_host',
'type'=>$emailsettingstype->id,
'value'=>'',
],
[
'name'=>'mail_port',
'type'=>$emailsettingstype->id,
'value'=>'',
],
[
'name'=>'mail_username',
'type'=>$emailsettingstype->id,
'value'=>'',
],
]);
The problem with above is that it won't update timestamps, find examples here
The Create many Method createMany is available on relationship check reference to this link and this documentation from laravel
so far my example look like this.
I have two models Pricing and AvailableService Model
Pricing Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pricing extends Model
{
protected $fillable = ["name", "price"];
public function available(){
return $this->hasMany(AvailableService::class, "pricing_id", "id");
}
}
And the AvailableServiceMode look like this
namespace App;
use Illuminate\Database\Eloquent\Model;
class AvailableService extends Model
{
protected $fillable = ["pricing_id", "service_id"];
public function service(){
return $this->belongsTo(Service::class, "service_id", "id");
}
}
So createMany operation look like this
$insertMany = Pricing::create(['name'=>request('name')]);
$insertMany->available()->createMany([
['service_id'=>1],
['service_id'=>2],
['service_id'=>3],
['service_id'=>4],
['service_id'=>5],
]);
And it works for, you can give it a try too. THANKS
If you want to store multiple record in seeder use this method instead of insert because in my case I want to slug automatically created using spatie/laravel-sluggable pkg. If you used the insert or DB technique then you have to give the value for slug field also.
CategorySeeder
<?php
namespace Database\Seeders;
use App\Servcategory;
use Illuminate\Database\Seeder;
class CategorySeeder extends Seeder
{
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
$categories = [
[
'name' => 'Automotive',
// 'slug' => 'automotive',
],
[
'name' => 'Business Services',
// 'slug' => 'business-services',
],
[
'name' => 'Computer, Telecom & IT Services',
// 'slug' => 'computer-telecom-&-it-services',
],
[
'name' => 'Education & Training',
// 'slug' => 'education-&-training',
],
[
'name' => 'Finance',
// 'slug' => 'finance',
],
[
'name' => 'Hospitals, Clinic, Medical',
// 'slug' => 'hospitals-clinic-medical',
],
[
'name' => 'Real Estate, Construction, Property',
// 'slug' => 'real-estate-construction-property',
],
[
'name' => 'Travel,Toursim & Hotels',
// 'slug' => 'travel-toursim-&-hotels',
],
];
// Servcategory::insert($categories);
collect($categories)->each(function ($category) { Servcategory::create($category); });
}
}
In case some one searching for eloquent model, I used the following method:
foreach($arCategories as $v)
{
if($v>0){
$obj = new Self(); // this is to have new instance of own
$obj->page_id = $page_id;
$obj->category_id = $v;
$obj->save();
}
}
$obj = new Self(); is a must otherwise it only saves single record when $this is used.
in seeder create an array and do foreach with Model::create(). All your records will be with timestamps
protected $array = [
[...],
[...],
[...]
];
public function run()
{
foreach ($this->array as $value) {
Model::create($value);
}
}

How to display activedataprovider data in gridview yii2

My array
$data = [
'subcategoryName' => 'asd',
'fromdate' => $fromdate,
'todate' => $todate,
'amount' => $finalamount,
];
Array data provider
$provider = new ArrayDataProvider([
'allModels' => $data,
'pagination' => [
'pageSize' => 10,
],
'sort' => [
'attributes' => ['subcategoryName'],
],
]);
// get the rows in the currently requested page
$rows = $provider->getModels();
return $rows;
Now I want to display this data on my grid view but I am getting this error Call to a member function getCount() on array
Please tell me that how can I display my array on yii2 grid view
You should'nt return here result of function getModels(). I assume u pass this to GridView, but u have to pass ArrayDataProvider.
Change this:
$rows = $provider->getModels();
return $rows;
To this:
return $provider;

Site and its behaviors do not have a method or closure named "orderBy"

while i am fetching this records then getting this error how to solve it ?
public function actionIndex()
{
$query = Site::model();
$pagination = new CPagination([
'defaultPageSize' => 5,
'totalCount' => $query->count(),
]);
$countries = $query->orderBy('name')
->offset($pagination->offset)
->limit($pagination->limit)
->all();
return $this->render('view', [
'countries' => $countries,
'pagination' => $pagination,
]);
}
you should distinguish between yii1 and yii2.from your codes,you used yii1 and yii2 together.

How do you return relational data from the yii2 REST API from a custom action?

I can't for the life of me figure out how to return relational data from the REST API from a custom action. For the default actions it is as easy as using the expand parameter in the request but I can't figure out how to do it for custom actions. I have tried many ways, here is the latest:
public function actionSearchbycity($city)
{
return new ActiveDataProvider([
'query' => School::find()->where(['city' => $city])->with('subjects')
]);
}
In the above example, as with all the other things I have tried this, only the School object is returned. I need the subject models as well.
Any ideas?
Try this
public function actionSearchbycity($city)
{
return new ActiveDataProvider([
'query' => School::find()->where(['city' => $city])->joinWith('subjects', false)
]);
}
If you overwrite the actions() and verbs() methods in your controller you can tell it to use a custom 'Action' model that you create.
public function actions()
{
return [
'index' => [
'class' => 'yii\rest\IndexAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
],
'searchByCity' => [
'class' => 'app\models\actions\SearchByCityAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
],
'view' => [
'class' => 'yii\rest\ViewAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
],
];
}
protected function verbs()
{
return [
'index' => ['GET', 'HEAD'],
'searchByCity' => ['GET', 'HEAD'],
'view' => ['GET', 'HEAD'],
];
}
Then you can create the SearchByCityAction by extending
yii\rest\Action
It might be easier to start with a copy of yii\rest\IndexAction.
As long as you have the subjects relation setup in the School model and you've overwritten the extraFields() or fields() method to include the relation in the array response it should return that data when you call your api.
Hope this helps.
In order to get the result based on custom relation, you can do like
public function actionSearchbycity($city)
{
$q = new yii\db\Query;
$query = $q->select('school.*, subject.*')
->from('school, subject')
->where('school.id = subject.school_id');
return new ActiveDataProvider([
'query' => $query
]);
}
Here I assumed that school and subject are two tables in your db & subject table has a column named school_id which is index key whose parent is school.id.
By doing so, you can retrieve all the columns of both the tables as per the relation between them specified in where(). And it can be applied as per your custom requirement and to all tables in your db.
Hope it helps someone looking for same.

Categories