Listview Itemid For Drag And Drop Sorting

Hello,

I am using jquery-ui sortable to order gridview and listview.

In Yii1 grid widget config I have used the following to create the row class item with dataprovider $data->id and parent $model->id

'rowCssClassExpression'=>'"items[]_{$data->id}|'. $model->id .'"' ,

In Yii2 listview i am using

‘itemOptions’ => [‘class’ => ‘items[]_{$data->id}|’. $model->id ],

but i realize that ‘$data’ does not exist and in this example it is also rendered as plain text and not variable.

How do i get the listview item id within the rendered item?

Thx

Dennis

Yii2 ListView has an itemView property that is a bit advanced than Yii1 because you can pass a view file to render OR a callback Closure function and do complex rendering. If you use a callback, the signature is something like this:




'itemView' => function ($model, $key, $index, $widget) {

   $id = $model->id;

   return your_own_view_render_method($id, $model);

}



Typically however you will directly use a view file like _view.php to render the list view items. You have the following parameters available within your _view.php.

[list=1]

[*]$model: mixed, the data model

[*]$key: mixed, the key value associated with the data item

[*]$index: integer, the zero-based index of the data item in the items array returned by [[dataProvider]].

[*]$widget: ListView, this widget instance

[/list]

But if you want to control the itemOptions there is no Closure method available for taking in item level model parameters. You may be able to play around with the view file to achieve a lot of styling related to each model.

But if you still need this, you may need to extend the ListView class and override the renderItems method.

Ok I finally figured out how to solve this sortable-serialize issue.

The goal is to send back a list to the server upon update.

The #listview is the top of the yii2 listview.

Sortable will work on the next level div. I am sure there might be a way to make it work on a nested div but i could not figure it out.

So the next div is usually the class=item in the list view which is controlled by ‘itemOptions’ => [‘class’ => ‘item’],

If you set ‘itemOptions’ => [‘tag’ => false], then there is not div set for each item.

And then in the _view you can create your own div with incrementing id.




<div id="item[]_<?php echo $model->id; ?>" class="list-container">






$(function() {

    $("#listview").sortable({

        placeholder: "ui-state-highlight",

        forcePlaceholderSize: true,

        forceHelperSize: true,

        update : function() {

            serial = $("#listview").sortable("serialize", {key:"item[]", attribute: "id"});

            $.ajax({

                url : "/controller/sort",

                type : "POST",

                data : serial,

                success : function(data) {

                    console.log("sorted: "+ serial);

                },

                "error": function(request, status, error) {

                    alert("We are unable to set the sort order at this time.  Please try again in a few minutes.");

                }

            });

        },

        // helper: fixHelper

    }).disableSelection();

});