Тут https://octoclub.ru/d/21-sortable-simple-tree-nested-tree Никита довольно понятно описал, что делать, если мы хотим сделать кастомную сортировку в нашем плагине.
А что если наши модели имеют вид Категория->Продукт? Что делать в этом случае? К счастью, у меня есть элегантный ответ на этот вопрос.
В данном уроке мы разберем простую связь. У Продукта это будет belongsTo Category. У Категории HasMany Products.
В обе модели внедряем sort_order (описано здесь https://octobercms.com/docs/backend/reorder или здесь https://octoclub.ru/d/21-sortable-simple-tree-nested-tree).
В Категории внедряем Relation manager (описано здесь https://octobercms.com/docs/backend/relations или в этом видео уроке от Watch and Learn https://www.youtube.com/watch?v=ssU7JdS3TII)
В папке модели Продукта создаем 2 файла: _reorder_handle.htm и columns_pivot.yaml
Содержимое _reorder_handle.htm:
<?php
echo '<div class="drag-handle" style="cursor: move"><input name="rcd[]" type="hidden" value="'.$record->id.'"/>☰</div>';
Содержимое columns_pivot.yaml:
columns:
sort_order_handle:
label: " "
type: partial
path: $/AthorName/PluginName/models/service/_reorder_handle.htm
sortable: false
width: 20px
sort_order:
invisible: true
type: number
sortable: true
name:
label: Name
searchable: true
sortable: false
align: left
- У Категории идем в config_relation.yaml
В view меняем стандартный columns.yaml на созданный нами columns_pivot.yaml
Пример:
services:
label: Service
manage:
form: $/authorname/pluginname/models/price/fields.yaml
list: $/authorname/pluginname/models/price/columns.yaml
view:
list: $/authorname/pluginname/models/price/columns_pivot.yaml
toolbarButtons: create|delete
defaultSort:
column: sort_order
direction: asc
- Идем в файл котроллера Категорий Categories.php
И в метод public function __construct() добавляем:
$this->addJs('https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js');
$this->addJs('/plugins/authorname/pluginname/assets/backend.js');
В этот же файл добавляем новый метод:
public function onReorderRelation()
{
$records = request()->input('rcd');
$model = new Service;
$model->setSortableOrder($records, range(1, count($records)));
Flash::success(trans('Order success'));
}
Соответственно подключаем нашу модель и Flash вверху файла:
use AuthorName\PluginName\Models\Service;
use Flash;
- Создаем assets/backend.js и вставляем туда:
function initializeSorting () {
if (typeof Sortable === 'undefined') return;
var $tbody = $('.drag-handle').parents('table.data tbody');
Sortable.create($tbody[0], {
handle: '.drag-handle',
animation: 150,
onEnd: function (evt) {
var $inputs = $(evt.target).find('td>div.drag-handle>input');
var $form = $('<form style="display: none;">');
$form.append($inputs.clone())
.request('onReorderRelation', {
complete: function () {
$form.remove();
}
});
}
});
}
$(function () {
initializeSorting();
$(window).on('ajaxUpdateComplete', initializeSorting)
});
Готово.