CGridView with jQueryUI sortable

Выкладываем свои наработки
Ответить
Аватара пользователя
Troy
Сообщения: 235
Зарегистрирован: 2011.02.03, 21:04

CGridView with jQueryUI sortable

Сообщение Troy »

Изображение

Для личных целей понадобилось прикрутить Drag&Drop сортировку записей в GridView, при этом добавить "буфер обмена", чтобы можно было сортировать записи с разных страниц. За помощь огромное спасибо nizsheanez.

Установка
Добавте колонку `sort` (intval) в таблицу с данными.
Подключите поведение для вашей модели:

Код: Выделить всё

public function behaviors()
{
    return array(
        'sortable' => array(
            'class' => 'ext.sortable.SortableBehavior',
            'column' => 'sort', // Default: sort
        )
    );
}
Подключите action к контроллеру и укажите экземпляр модели, для которой будет применяться сортировка:

Код: Выделить всё

public function actions()
{
    return array(
        'sortable' => array(
            'class' => 'ext.sortable.SortableAction',
            'model' => YourModel::model(),
            'column' => 'sort', // Default: sort
        )
    );
} 
Замените использование CGridView:

Код: Выделить всё

$this->widget('CGridView', array( 
На SortableGridView:

Код: Выделить всё

$this->widget('SortableGridView', array( 
Скачать
GitHub
bookin
Сообщения: 37
Зарегистрирован: 2011.01.28, 12:43

Re: CGridView with jQueryUI sortable

Сообщение bookin »

Добавлю:
В конфиге подключаем:

Код: Выделить всё

'import'=>array(
           'ext.sortable.*'
);
Для тех как я, которые используют стандартный роут, не подходит то что есть, поэтому
В классе SortableColumn.php заменяем 18 строку:

Код: Выделить всё

$this->url = Yii::app()->createUrl(preg_replace('#' . Yii::app()->controller->action->id . '$#', 'sortable', Yii::app()->controller->route));

Далее что бы указать название ключа в таблице:
В классе SortableAction.php
добавляем:

Код: Выделить всё

public $id_key = 'id';
заменяем 20 строку:

Код: Выделить всё

$max = (int) Yii::app()->db->createCommand("SELECT MAX({$this->column}) FROM " . $this->model->tableName() . " WHERE {$this->id_key} IN(" . implode(', ', $_POST['ids']) . ")")->queryScalar();
В классе SortableBehavior.php
добавляем:

Код: Выделить всё

public $id_key = 'id';
заменяем 42 строку:

Код: Выделить всё

Yii::app()->db->createCommand("UPDATE " . $this->getOwner()->tableName() . " SET {$this->column} = " . $this->_generateCase($priorities) . " WHERE {$this->id_key} IN(" . implode(', ', $ids) . ")")->execute();
заменяем 51 строку:

Код: Выделить всё

Yii::app()->db->createCommand("UPDATE " . $this->getOwner()->tableName() . " SET {$this->column} = {$this->id_key}")->execute();
заменяем 57 строку:

Код: Выделить всё

$result = 'CASE `'.$this->id_key.'`';
теперь при подключении поведения к модели и при подключения экшина в контроллере, можно использовать собственное поле:

Код: Выделить всё

public function behaviors()
        {
            return array(
                'sortable' => array(
                    'class' => 'ext.sortable.SortableBehavior',
                    'id_key'=>'category_id',
                    'column' => 'position', // Default: sort
                )
            );
        }

public function actions()
        {
            return array(
                'sortable' => array(
                    'class' => 'ext.sortable.SortableAction',
                    'model' => Category::model(),
                    'id_key'=>'category_id',
                    'column' => 'position', // Default: sort
                )
            );
        }
Для тех кому не хочется все время указывать названия полей которые нужно вывести в грид:

В классе SortableGridView.php между строками 19 и 20 вставляем:

Код: Выделить всё

            if (empty($array)){
                $model_colums=$this->dataProvider->model->attributes;
                foreach ($model_colums as $name=>$value)
                    array_push($this->columns,$name);
            }
Для тех кто хочет ставить колонку с элементом для сортировки не только в конец но и в начало:
В классе SortableGridView.php
добавляем публичную переменную:

Код: Выделить всё

public $sort_position='first';
заменяем строки 24,25 на:

Код: Выделить всё

           if ($exists === false){
                if($this->sort_position==='last')
                    array_push($this->columns, array('class' => 'SortableColumn'));
                else
                    array_unshift($this->columns, array('class' => 'SortableColumn'));
            }
теперь по дефолту у нас колонка устанавливается в начале, если требуется установить ее в конец, при вызове виджета SortableGridView пишем:

Код: Выделить всё

$this->widget('SortableGridView', array(
    'dataProvider'=>$dataProvider,
    'sort_position'=>'last'
));
Ответить