Suppose you have Products,Categories and each product belongs in many categories
Product (id,name) Category (id,name) ProductCategory (id,productId,categoryId,Order)
Suppose also that the Order define the priority of the product category or any other meaning of "order" priority
You know how to display the categories of a product (using CGridView or CListView) but how can change their ordering in easy way?
The main way is using a text for each record tha define the order, but you have to change each record separately
For example you have the order of products
id3=>order1
id4=>order2
id1=>order3
id2=>order4
If you want to change id3 order and put it between id1 and id2 then
id3=>order3
id4=>order1
id1=>order2
id2=>order4
many changes and tiring especially for many items
Drupal CMS makes it using drag&drop. I will show how to do that in Yii
In your view of product
$relProvider = new CArrayDataProvider($model->categories, array(
'keyField' => 'id', //optional
'pagination' => array(
'pageSize' => 200,
),
));
$this->widget('zii.widgets.CListView', array(
'dataProvider' => $relProvider,
'id' => 'items-list',
'itemView' => '_item',
'template' => "{pager}{items}",
'afterAjaxUpdate' => 'function (id,data) {refreshSortable(); }',
));
<script>
$(document).ready(function() {
refreshSortable();
});
function refreshSortable() {
$("#items-list .items").sortable(
{stop: function(event, ui) {
saveOrder(event, ui);
}}
);
}
function saveOrder(event, ui) {
var order = [];
$('#items-list .items #item_id').each(function(k, v) {
var v1 = $(v).val();
order.push(v1);
}
);
$.ajax({
type: "POST",
url: "<?php echo $this->createUrl('setOrder',array('productId'=>$model->id));?>",
dataType: 'json',
data: {data: order}
});
}
</script>
In _item.php (related category)
<?php echo $form->hiddenField($data, 'id'); ?>
<div class="view">
<?php echo CHtml::encode($data->name); ?>
</div>
...
And In yourController.php
//data variable has data like {productId1,roductId4,roductId2} (order is important that generated from saveOrder javascript function)
public function actionSetOrder($productId) {
if (isset($_POST['data'])) :
$data = $_POST['data'];
$mods = array();
$ords = array();
$ai = 0;
foreach ($data as $i):
$m = ProductCategory::model()->findByAttributes(array('categoryId' => $i, 'productId' => $i));
if ($m) : //collect All posted ProductCategories and its order
$mods[] = $m;
$ords[] = ($m->Order != 0) ? $m->Order : ++$ai;
endif;
endforeach;
sort($ords); //set in order collected orders
$pr = 0;
foreach ($ords as &$o): //if a record has the same order with another one shift by one
if ($pr == $o) {
$o++;
}
$pr = $o;
endforeach;
$idx = 0;
foreach ($mods as $m) : //set the new order foreach model that involved in this action
$m->Order = $ords[$idx];
$m->save();
$idx++;
endforeach;
endif;
}
That's it!
Bootstrap TbListView
It's possible with Bootstrap TbListView???
Re: #17655
TbListView extends zii.widgets.CListView
I didn't tested but I am sure that the answer is yes! :)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.