Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions backend/lists.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ Option | Description
`showTotals` | displays the summed values for the columns in the form of `totalOnPage (totalForQuery)` in the list header and footer. Default: `true`.
`treeExpanded` | if tree nodes should be expanded by default. Default: `false`.
`customViewPath` | specify a custom view path to override partials used by the list, optional.
`sortable` | enables drag-and-drop reordering of records directly in the list, see [reordering records](#reordering-records). Default: `false`.

### Reordering records

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.

```yaml
sortable: true
```

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.

> **NOTE:** Reordering applies to flat lists. For reordering tree structures, or for a dedicated standalone reordering page, use the [Reorder behavior](reorder).

### Adding a toolbar

Expand Down
16 changes: 16 additions & 0 deletions backend/relations.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ Option | Type | Description
`recordUrl` | List | link each list record to another page. Eg: **users/update/:id**. The `:id` part is replaced with the record identifier.
`customViewPath` | List | specify a custom view path to override partials used by the list.
`recordOnClick` | List | custom JavaScript code to execute when clicking on a record.
`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`.
`toolbarPartial` | Both | a reference to a controller partial file with the toolbar buttons. Eg: **_relation_toolbar.htm**. This option overrides the *toolbarButtons* option.
`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.

Expand Down Expand Up @@ -289,6 +290,21 @@ phone:
list: $/acme/user/models/phone/columns.yaml
```

### Reordering relations

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:

```yaml
authors:
label: Author
view:
list: $/acme/blog/models/author/columns.yaml
toolbarButtons: link|unlink
sortable: true
```

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.

## Displaying a relation manager

Before relations can be managed on any page, the target model must first be initialized in the controller by calling the `initRelation` method.
Expand Down
2 changes: 2 additions & 0 deletions backend/reorder.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

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.

> **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.

The behavior depends on a [model class](../database/model) which must implement one of the following [model traits](../database/traits):

1. [`Winter\Storm\Database\Traits\Sortable`](../database/traits#sortable)
Expand Down
43 changes: 38 additions & 5 deletions database/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -838,16 +838,49 @@ class ApiData extends Model

## HasSortableRelations

Add this trait to your model in order to allow its relations to be sorted/reordered.
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.

```php
class MyModel extends model
class Article extends \Winter\Storm\Database\Model
{
use \Winter\Storm\Database\Traits\HasSortableRelations;

/**
* @var array Relations that can be sorted/reordered and the column name to use for sorting/reordering.
* @var array Relations that can be reordered and the pivot column used for sorting.
*/
public $sortableRelations = ['relation_name' => 'sort_order_column'];
...
public $sortableRelations = ['authors' => 'sort_order'];

public $belongsToMany = [
'authors' => [
\Acme\Blog\Models\Author::class,
'table' => 'acme_blog_articles_authors',
],
];
}
```

Ensure the pivot table has the sort order column, for example in a migration:

```php
$table->integer('sort_order')->default(0);
```

When the trait boots it automatically adds the sort order column to the relation's pivot data and applies an `order by {pivot_table}.{column} asc` clause, so the relation is always returned in its stored order. Newly attached records are appended to the end of the relation automatically.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

Use the `setRelationOrder` method to reorder a relation programmatically. Pass the related record ids in their new order; an optional second argument provides the sort order value to assign to each (when omitted, a sequential `1..N` order is assigned in the given order):

```php
// Assign sort orders 1, 2, 3 to the given records, in this order
$article->setRelationOrder('authors', [$author3->id, $author1->id, $author2->id]);

// Assign explicit sort order values
$article->setRelationOrder('authors', [1, 2, 3], [3, 2, 1]);
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

You can check whether a relation is configured as sortable with `isSortableRelation`:

```php
$article->isSortableRelation('authors'); // true
```

> **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.
Loading