You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: backend/lists.md
+13Lines changed: 13 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -76,6 +76,19 @@ Option | Description
76
76
`showTotals` | displays the summed values for the columns in the form of `totalOnPage (totalForQuery)` in the list header and footer. Default: `true`.
77
77
`treeExpanded` | if tree nodes should be expanded by default. Default: `false`.
78
78
`customViewPath`| specify a custom view path to override partials used by the list, optional.
79
+
`sortable`| enables drag-and-drop reordering of records directly in the list, see [reordering records](#reordering-records). Default: `false`.
80
+
81
+
### Reordering records
82
+
83
+
Set `sortable` to `true` to let backend users reorder the list with drag-and-drop. The list model must use the [`Sortable` trait](../database/traits#sortable) so it has a `sort_order` column.
84
+
85
+
```yaml
86
+
sortable: true
87
+
```
88
+
89
+
When enabled, a drag handle is shown on each row, column header sorting and pagination are disabled (every record is shown in its stored order), and dropping a row persists the new order to the model's sort order column via AJAX.
90
+
91
+
> **NOTE:** Reordering applies to flat lists. For reordering tree structures, or for a dedicated standalone reordering page, use the [Reorder behavior](reorder).
Copy file name to clipboardExpand all lines: backend/relations.md
+16Lines changed: 16 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -114,6 +114,7 @@ Option | Type | Description
114
114
`recordUrl` | List | link each list record to another page. Eg: **users/update/:id**. The `:id` part is replaced with the record identifier.
115
115
`customViewPath`| List | specify a custom view path to override partials used by the list.
116
116
`recordOnClick`| List | custom JavaScript code to execute when clicking on a record.
117
+
`sortable`| List | enables drag-and-drop reordering of the related records, see [reordering relations](#reordering-relations). Requires the parent model to use the [`HasSortableRelations` trait](../database/traits#hassortablerelations). Default: `false`.
117
118
`toolbarPartial` | Both | a reference to a controller partial file with the toolbar buttons. Eg: **_relation_toolbar.htm**. This option overrides the *toolbarButtons* option.
118
119
`toolbarButtons` | Both | the set of buttons to display. This can be formatted as an array or a pipe separated string, or set to `false` to show no buttons. Available options are: `create`, `update`, `delete`, `add`, `remove`, `refresh`, `link`, & `unlink`. Example: `add\|remove`. <br/> Additionally, you can customize the text inside these buttons by setting this property to an associative array, with the key being the button type and the value being the text for that button. Example: `create: 'Assign User'`. The value also supports translation.
119
120
@@ -289,6 +290,21 @@ phone:
289
290
list: $/acme/user/models/phone/columns.yaml
290
291
```
291
292
293
+
### Reordering relations
294
+
295
+
Pivot-based relations (`belongsToMany`, `morphToMany`, `morphedByMany`) can be reordered with drag-and-drop directly in the relation manager. The parent model must use the [`HasSortableRelations` trait](../database/traits#hassortablerelations) and declare the relation in its `$sortableRelations` property, and the pivot table must have a sort order column. Then set `sortable: true` on the relation's `view` configuration:
296
+
297
+
```yaml
298
+
authors:
299
+
label: Author
300
+
view:
301
+
list: $/acme/blog/models/author/columns.yaml
302
+
toolbarButtons: link|unlink
303
+
sortable: true
304
+
```
305
+
306
+
A drag handle is shown on each related record; dropping persists the new order to the pivot's sort order column. Reordering also works while the parent record is being created, before it is saved — the order is stored against the [deferred binding](../database/relations#deferred-binding) and committed together with the record.
307
+
292
308
## Displaying a relation manager
293
309
294
310
Before relations can be managed on any page, the target model must first be initialized in the controller by calling the `initRelation` method.
Copy file name to clipboardExpand all lines: backend/reorder.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,8 @@
4
4
5
5
The **Reorder behavior** is a controller [behavior](../services/behaviors) that provides features for sorting and reordering database records. The behavior provides a page called Reorder using the controller action `reorder`. This page displays a list of records with a drag handle allowing them to be sorted and in some cases restructured.
6
6
7
+
> **NOTE:** To let users reorder records inline with drag-and-drop without a dedicated page — directly in a [list](lists#reordering-records) or a [relation manager](relations#reordering-relations) — see those sections. The Reorder behavior documented here provides a dedicated standalone page, which is best suited to models with deep tree structures.
8
+
7
9
The behavior depends on a [model class](../database/model) which must implement one of the following [model traits](../database/traits):
Copy file name to clipboardExpand all lines: database/traits.md
+38-5Lines changed: 38 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -838,16 +838,49 @@ class ApiData extends Model
838
838
839
839
## HasSortableRelations
840
840
841
-
Add this trait to your model in order to allow its relations to be sorted/reordered.
841
+
Sorted relations store a sort order value in the pivot table of a `belongsToMany`, `morphToMany`, or `morphedByMany` relation, so the related records keep a custom order for each parent record. Apply the `Winter\Storm\Database\Traits\HasSortableRelations` trait and define a `$sortableRelations` property that maps each relation name to its pivot sort order column.
842
842
843
843
```php
844
-
class MyModel extends model
844
+
class Article extends \Winter\Storm\Database\Model
845
845
{
846
846
use \Winter\Storm\Database\Traits\HasSortableRelations;
847
847
848
848
/**
849
-
* @var array Relations that can be sorted/reordered and the column name to use for sorting/reordering.
849
+
* @var array Relations that can be reordered and the pivot column used for sorting.
850
850
*/
851
-
public $sortableRelations = ['relation_name' => 'sort_order_column'];
852
-
...
851
+
public $sortableRelations = ['authors' => 'sort_order'];
852
+
853
+
public $belongsToMany = [
854
+
'authors' => [
855
+
\Acme\Blog\Models\Author::class,
856
+
'table' => 'acme_blog_articles_authors',
857
+
],
858
+
];
853
859
}
860
+
```
861
+
862
+
Ensure the pivot table has the sort order column, for example in a migration:
863
+
864
+
```php
865
+
$table->integer('sort_order')->default(0);
866
+
```
867
+
868
+
You must create the column yourself (as in the migration above) — the trait does not create it. When the model boots, the trait includes that column in the relation's pivot data, so its value is loaded onto each record's `pivot`, and applies an `order by {pivot_table}.{column} asc` clause so the relation is always returned in its stored order. The trait also assigns the next sort order value to newly attached records, appending them to the end of the relation.
869
+
870
+
Use the `setRelationOrder` method to reorder a relation programmatically. The second argument is the related record ids in their new order; the optional third argument provides the sort order value to assign to each (when omitted, a sequential `1..N` order is assigned in the given order):
871
+
872
+
```php
873
+
// Reorder by ids only — assigns sort orders 1, 2, 3 in the given order
You can check whether a relation is configured as sortable with `isSortableRelation`:
881
+
882
+
```php
883
+
$article->isSortableRelation('authors'); // true
884
+
```
885
+
886
+
> **NOTE:** To let backend users reorder a relation with drag-and-drop directly in a form, see [reordering relations](../backend/relations#reordering-relations) in the RelationController documentation.
0 commit comments