Custom sorter for ListView in Yii2
The standard ListView widget automatically creates a sort of sort by having a section {sorter}
in the property $layout
. However, for my grocery list, I need a more complex sorter with a custom template.
Essentially I need to be able to:
- Sorting the list by several fields (popularity, novelty, price, etc.).
- Select the number of records per page (12, 50, 100)
- Switch between two different view templates (more / less product information)
At this point I am trying to figure out if I need to create a descendant of a class from ListView
or if I can customize the properties of existing classes.
What is the best practice for implementing something like this?
source to share
1) You can customize sorter
as follows:
<?= ListView::widget([
'layout' => "{sorter}\n{summary}\n{items}\n{pager}", // Add sorter to layout because it turned off by default
'sorter' => [
// ...
],
]) ?>
See yii \ widgets \ LinkSorter for available properties in the official documentation .
But there are no styling options, so you need a different soul (the default sorter is simple ul
).
You have two options here.
You can create your own class that extends from yii\widgets\LinkSorter
and overrides the method renderSortLinks()
that is responsible for rendering the html.
Then replace the default sorter
with ListView
:
<?= ListView::widget([
'sorter' => [
'class' => CustomLinkSorter::className(),
],
]) ?>
But I recommend using a different method. Don't plug {sorter}
in layout
and just create your own sorter that suits your needs. Insert an inner shape and enter a name sort
to select. You can still customize the attribute list and other options in the configuration for the sorter.
You also need to specify values ββto select such parameters:
popularity
- order by popularity (ascending),
-popularity
- order by popularity (desc).
2) As I recall, Yii 2 has no built-in options for making such a selection. You have to do it yourself. Create a select box, give it a name per-page
in general form (this is the default name to limit the number of records per page). The selection names and values ββcorrespond to the required account.
You first need to override the default Pagination values in yours dataProvider
before you pass it to ListView
:
$dataProvider->pagination = [
'defaultPageSize' => 12,
'pageSizeLimit' => [12, 100],
],
Then just pass it ListView
:
<?= ListView::widget([
'dataProvider' => $dataProvider,
]) ?>
Also check this extension out if you found it useful.
3) It can be solved as follows. Since there are only two templates, you can add something like this to your form parameter advanced-view
. Thus, the main template appears when this parameter is not set or equal 0
, and the extended template matches the value 1
.
In ListView
you can toggle them depending on the value / existence of this GET parameter:
<?= ListView::widget([
'itemView' => Yii::$app->request->get('advanced-view') ? '_advanced-view' : '_basic-view',
]) ?>
source to share