How do I Dynamically show the pageSize in yii2? - filter

For now I have set static pagesize in my search function, but now I need to create dropdown for user to change the pagesize from front end. For e.g like 10,20,50,100.
I got the code but it is for yii previous version.

If I had to do it I will use the following approach.
Create a Dropdown for the page sizes, you can adjust the dropdown inside the layout option of the gridview if you want it between summary text and items list or add it before the gridview. like this image, you can wrap it with div to adjust the CSS for it yourself.
The main thing to do is to include the id of the drop-down to the filterSelector option so that every time the gridview is filtered the dropdown value is also submitted and also whenever you change the dropdown.
Your GridView will look like below
GridView::widget([
'dataProvider' => $dataProvider,
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [1 => 10, 2 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
'filterModel' => $searchModel,
'filterSelector' => '#myPageSize',
'columns'=>[
// your column configurations.......
]
]);
Declare a public property in the searchModel
public $myPageSize
Add that property to the safe rules inside your searchModel
[['myPageSize'],'safe']
And then update you search() method inside the relative SearchModel you are using with the GridView. You should assign the pageSize option of the query inside the $dataProvider with the new property defined but make sure you add this line after the $this->load($params) statement.
See below
$dataProvider->pagination->pageSize = ($this->myPageSize !== NULL) ? $this->myPageSize : 10;`
Here we are setting the default page size equal to the minimum option inside the drop-down we created, otherwise it would be updated when ever you change the dropdown.
Now try changing the dropdown you will see it working. Hope this helps

Thank you Muhammad!
Your answer helped me, but on the layout I had to modify the array for the select:
Where you have "1 => 10, 2 => 20," I had to change it to "10 => 10, 20 => 20,". Otherwise it pagination goes one by one or two by two.
It ended up like this:
'layout'=>'{summary}'.Html::activeDropDownList($searchModel, 'myPageSize', [10 => 10, 20 => 20, 50 => 50, 100 => 100],['id'=>'myPageSize'])."{items}<br/>{pager}",
The rest worked perfect!

Related

Kendo TreeView in grid display 'undefined'

I had this kendo grid demo, and on outletID column, i want to use kendoTreeView with checkbox, so multiple selected outletID possible. But when edit it display undefined result, and the template that display outletName also not working. Appreciate your help
DEMO IN DOJO
Your tree needs dataTextField and dataValueField set.
Your column template doesn't know where to look for the outletName. Kendo supports 1-N relationships, but I'm not aware of N-N.
The data in your template is the current row of the grid. For the first row, that would be {"id":"1","outletID":"LA2,LA3","accountName":"Data1"}. You need to process that data yourself. For instance:
template: "#= (data.outletID) ? data.outletID.split(',')
.map(x => TreeData.find(y => y.outletID == x)['outletName']) : '' #"
For the editor, the value of a dropDownTree is an array. Your row has a string. You need to do two things:
1 . Init the editor's value in the function outletTree:
if (options.model) {
ddt.value((options.model[options.field] || '').split(','))
}
2 . When the dropDownTree's value changes, update your grid row:
change: e => {
const value = e.sender.value();
console.log(value)
options.model.set(options.field, value.join(','))
}
Here's an updated dojo: https://dojo.telerik.com/#GaloisGirl/oYEGerAK . The "Update" button doesn't work yet, probably because the dataSource must support edition. Here is how to do it on local data.

Yii2 cache of grid view

I have a relatively complex query across 8 tables which returns up to 10,000 records with 20 columns. These are then displayed in a GridView
The user repeatedly sorts and filters the GridView - causing a page reload - in order to rank the data. One column contains an Ajax “five star” rating function and the user then marks each row: one star to five stars
Naturally, this isn’t the fastest loading page so I was wondering if I could use caching to accelerate the page load but don’t know if this can be done considering the filtering and marking
Can caching be used in this example? The data in the 19 columns are always the same (the user cannot change the data) but the user constantly changes the rating in the 20th column
Can I cache the 19 columns and filter / sort after??
Can I cache the 19 columns and join the rating column thereafter??
Many thanks
You can easily use the PageCache filter behavior of yii2 to easily cache pages.
Just add the following code to your controller and fit the dependency and variation properties to your needs.
public function behaviors()
{
return [
'pageCache' => [
'class' => 'yii\filters\PageCache',
'only' => ['index'],
'duration' => 60,
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM post',
],
'variations' => [
\Yii::$app->language,
]
],
];
}

Comparing laravel collections

I have two collections: "Instructions" and "Known". Basically I am taking a new set of "Instructions" and checking whether anything is different to what is "Known".
So, the quantity is not massive. I retrieve the info:
$Instructions = Instruction::all();
$Knowns = Known::all();
Now, I'm looking for the differences, and I've tried each of these three methods:
$IssuesFound = $Instructions->diff($Knowns);
$IssuesFound = $Instructions->diffKeys($Knowns);
$IssuesFound = $Instructions->diffAssoc($Knowns);
The thing is, an "Instruction" or "Known" is an item with 17 attributes, and anyone of those attributes can be different. I want to compare the attributes of an "Instruction" with the matching attribute of a "Known". (Both items have the same keys, bot items have a Reference attribute to act as a unique identifier.
What I'm finding is that theese methods give me the item that is different, but doesn't tell me which individual attributes are the mismatch.
foreach ($IssuesFound as $issue)
{
dd($issue);
}
So a method like $IssuesFound = $Instructions->diffKeys($Knowns); will come up with item xxx being different, but I can't see how to find out which attribute of the item it is that is different. Not unless I start nesting loops and iterating through all the attributes - which I'm trying to avoid.
How do I do it?
Thanks in advance. (Laravel 5.6)
Straight from laravel docs, diffAssoc will return what you are asking:
$collection = collect([
'color' => 'orange',
'type' => 'fruit',
'remain' => 6
]);
$diff = $collection->diffAssoc([
'color' => 'yellow',
'type' => 'fruit',
'remain' => 3,
'used' => 6
]);
$diff->all();
// ['color' => 'orange', 'remain' => 6]
You get the attribute from the FIRST collection that is different on the SECOND collection, therefore if you get 3 attributes when calling $diff->all() you will know WHICH attributes ARE DIFFERENT, so you could access them or do whatever you want to, if you post more specific results of what you are getting and what you are trying we can help, but I think you are just not thinking how to use these methods

Yii - sort dataprovider with more than one field

I am using DataProvider to show some data. The data is related to shows in the theater. I want to show the shows which are "On Season" first and then the shows that are not on season. And all the shows should be ordered alphabetically. I tried to use CSort but I am getting an error. Here is my code:
$dataProviderFiaba = new CActiveDataProvider('Show',
array(
'criteria'=>array(
'condition'=>'show_type= '.Show::TYPE_FIABA,
),
'sort'=>array(
'defaultOrder'=>'on_season', //TO SHOW THE ON SEASON SHOWS FIRST
'asc'=>'title', // TO ORDER ALPHABETICALLY
),
));
And the error is Property "CSort.asc" is not defined. So I think I am not using CSort with the correct format. What is the right way to do this kind of sorting?
You can only use "asc" in the context of attributes for CSort. For example:
$mCSort->attributes = array('title'=>array('asc'=>'title', 'desc' => 'title DESC'));
To solve your sorting problem, the following should be sufficent though:
$dataProviderFiaba = new CActiveDataProvider('Show',
array(
'criteria'=>array(
'condition'=>'show_type= '.Show::TYPE_FIABA,
'order'=>'on_season, title'
),
));

Extending an attribute by adding a property

I have a Magento site which will contain many attributes and attribute sets. Each category will have its own set and the customer wants the category and products view to show different attributes depending on which category it is in.
This would be easy enough to do in a switch / if statement but I don't want to hard code if possible.
My idea was to add a new property to the attributes called. 'display_on_frontend' which I could then use in a loop to see if an attribute should be displayed. Would this be possible to do?
There is a property already called Visible on Product View Page on Front-end which I initially wanted to use but when I get the attribute, it's not available in the data.
Here's the code that I am using to get the attributes on the product view
$_attributes = Mage::getModel('catalog/product_attribute_api')->items($_product->getAttributeSetId());
foreach ($_attributes as $_attribute) :
$attributeFull = Mage::getResourceModel('eav/entity_attribute_collection')
->setCodeFilter($_attribute['code'])
->getFirstItem();
endforeach;
An example response of what is returned is
[_data:protected] => Array
(
[attribute_id] => 139
[entity_type_id] => 4
[attribute_code] => safe_working_load_range_tonnes
[attribute_model] =>
[backend_model] =>
[backend_type] => int
[backend_table] =>
[frontend_model] =>
[frontend_input] => select
[frontend_label] => Safe Working Load (Tonnes)
[frontend_class] =>
[source_model] => eav/entity_attribute_source_table
[is_required] => 0
[is_user_defined] => 1
[default_value] =>
[is_unique] => 0
[note] =>
)
Does anyone have any suggestions on how to extend the attribute or on a reasonable way to address the problem?
Thank you
In the back end, when you created the attribute, there's a yes/no select that's labelled "Visible on Product View Page on Front-end".
Go to Admin > Catalog > Attributes > Manage Attributes > select your attribute "display_on_frontend" > Frontend Properties > Change "Visible on Product View Page on Front-end" to "Yes".
Then to access the value of that attribute, you can simply call:
$_product->getData("display_on_frontend");
or just use the camel-case getter:
$_product->getDisplayOnFrontend();

Resources