> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/umbraco-cms/17.latest/extend-your-project/backoffice-extensions/property-editors/sorting.md).

# UI Sorting

Enable sorting elements via drag and drop

{% hint style="warning" %}
This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
{% endhint %}

The Umbraco Sorter enables you to make a list of elements sortable via drag-and-drop interaction. You have to set up the sorter once on the Element that renders the items to be sorted. As part of the configuration, you shall provide an `onChange` callback method, which will be executed every time the sorter makes a difference to the data.

### Configuration

The following example shows a basic setup of the Sorter.

```typescript

type ModelEntryType = {
    id: string;
    name: string;
}

this.#sorter = new UmbSorterController(this, {
    itemSelector: '.sorter-item',
    containerSelector: '.sorter-container',
    getUniqueOfElement: (element) => {
        return element.getAttribute('data-sorter-id');
    },
    getUniqueOfModel: (modelEntry) => {
        return modelEntry.id;
    },
    onChange: ({ model }) => {
        const oldValue = this._items;
        this._items = model;
        this.requestUpdate('_items', oldValue);
    },
});
```

The properties provided are the following:

* `itemSelector`: A query selector that matches the items that should be draggable.
* `containerSelector`: A query elector that matches the parent element of the items.
* `getUniqueOfElement`: A method that returns the unique element
* `getUniqueOfModel`: Provide a method that returns the unique of a given model entry
* `onChange`: Provide a method to retrieve the changed model. This is called every time the model is changed, including when the user is dragging around.

### Data Model

The model given to the Sorter must be an Array. The following example extends the example from above:

```typescript

    const model: Array = [
        {
            id: 1,
            name: 'First item'
        },
        {
            id: 2,
            name: 'second item'
        }
        {
            id: 3,
            name: 'Third item'
        }
    ]

    // Set the Model, if you have changes to the model not coming from the Sorter. Then set the model again:
    this.#sorter.setModel(model);
```

### Rendering

The Sorter does not move elements, instead, it updates the model as the user drags an item around. This puts higher pressure on the rendering of the sortable Elements. This means we need to make sure that the rendering re-uses the same element despite sorting the data differently.

Lit does provide a render helper method called `repeat` that does this for us. The following example shows a render method that continues the work of the examples above:

```typescript


    render() {
		return html`
			<div class="sorter-container">
				${repeat(
					this._items,
					(item) => item.id,
					(item) =>
						html`
                            <p class="sorter-item" data-sorter-id="${item.id}">${item.name}</p>
						`,
				)}
			</div>
		`;
	}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umbraco.com/umbraco-cms/17.latest/extend-your-project/backoffice-extensions/property-editors/sorting.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
