Sortable List
Sortable lists is an extension of List View that allows you to sort list view elements.
Sortable List Layout
Let’s look at layout structure of sortable lists in your list views:
<!-- Additional "sortable" class on list block -->
<div class="list sortable">
<li>
<div class="item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<!-- Sortable handler element -->
<div class="sortable-handler"></div>
</li>
...
</div>
Where:
sortable-handler
- “draggable” element (hidden by default) that allows you to sort current list view element
As you may see it is pretty simple, all you need is to add sortable
class to list block and put <div class="sortable-handler"></div>
as a direct child of <li>
.
Disable Sorting
If we need to disable sorting on some specific items we can add no-sorting
or disallow-sorting
class to those items:
<!-- Additional "sortable" class on list block -->
<div class="list sortable">
<!-- disable sorting for this item -->
<li class="no-sorting">...</li>
<!-- sortable items -->
<li>...</li>
<li>...</li>
</div>
Note, that it makes sense and work only on first or last items in the list and won’t work correctly if you disable sortable for some of the items in the middle.
Opposite Sortable
If we need to render sortable handler on opposite side (e.g. on left in LTR direction) we need to add sortable-opposite
side to sortable list:
<!-- Additional "sortable-opposite" class on sortable list -->
<div class="list sortable sortable-opposite">
<li>
<div class="item-content">
<div class="item-media">...</div>
<div class="item-inner">...</div>
</div>
<!-- Sortable handler element -->
<div class="sortable-handler"></div>
</li>
...
</div>
Sortable App Methods
To enable/disable sorting mode on sortable list we need to use following app methods:
app.sortable.enable(listEl)- enable sorting mode on sortable list
- listEl - HTMLElement or string (with CSS Selector). Sortable list block element.
app.sortable.disable(listEl)- disable sorting mode on sortable list
- listEl - HTMLElement or string (with CSS Selector). Sortable list block element.
app.sortable.toggle(listEl)- toggle sorting mode on sortable list
- listEl - HTMLElement or string (with CSS Selector). Sortable list block element.
Sortable App Parameters
It is possible to configure global sortable behavior on app initialisation by passing sortable related paremeters under sortable
property.
Parameter | Type | Default | Description |
---|---|---|---|
moveElements | boolean | true | When enabled then it will move (reorder) HTML elements according to new sortable order. It is useful to disable it if you use other library for DOM manipulation, like React or Vue. It is also possible to overwrite this behavior for specific lists by adding |
To change these parameters we need to pass them on app init under sortable
property, for example:
var app = new Framework7({
sortable: {
moveElements: false
}
});
Sortable Events
Sortable will fire the following DOM events on sortable list block element and events on app instance:
DOM Events
Event | Target | Description |
---|---|---|
sortable:enable | Sortable List<div class=”list sortable”> | Event will be triggered when sortable mode is enabled |
sortable:disable | Sortable List<div class=”list sortable”> | Event will be triggered when sortable mode is disabled |
sortable:sort | List element<li> | Event will be triggered after user release currently sorting element in new position. event.detail will contain object with from and to properties with from/to index numbers of sorted list item and el property with HTML sorted element |
App Instance Events
Sortable instance emit events on app instance.
Event | Target | Arguments | Description |
---|---|---|---|
sortableEnable | app | listEl | Event will be triggered when sortable mode is enabled |
sortableDisable | app | listEl | Event will be triggered when sortable mode is disabled |
sortableSort | app | listEl, data | Event will be triggered after user release currently sorting element in new position. data is an object with from and to properties with from/to index numbers of sorted list item el property with HTML sorted element |
Sortable On Tap Hold
It is possible to bypass sortable enable/disable logic and make list items sortable on item tap and hold (long press). To make it work, we just need additional sortable-tap-hold
class on sortable list:
<!-- additional "sortable-tap-hold" class on sortable list -->
<div class="list sortable sortable-tap-hold">
...
</div>
In this case app will rely on custom taphold
event. To make it work correctly, make sure you have also enabled touch.tapHold: true
app parameter
Control Sortable With Links
It is possible to enable and disable sortable mode using special classes and data attributes on links:
To enable sortable mode we need to add
sortable-enable
class to any HTML element (prefered to link)To disable sortable mode we need to add
sortable-disable
class to any HTML element (prefered to link)To toggle sortable mode we need to add
sortable-toggle
class to any HTML element (prefered to link)If you have more than one sortable list in app, you need to specify appropriate sortable list via additional
data-sortable=".sortable"
attribute on this HTML element with CSS selector of required sortable list
CSS Variables
Below is the list of related CSS variables (CSS custom properties).
:root {
--f7-sortable-handler-color: rgba(0, 0, 0, 0.22);
--f7-sortable-sorting-item-bg-color: rgba(255, 255, 255, 0.8);
}
:root .theme-dark,
:root.theme-dark {
--f7-sortable-sorting-item-bg-color: rgba(50, 50, 50, 0.8);
--f7-sortable-handler-color: rgba(255, 255, 255, 0.55);
}
.ios {
--f7-sortable-handler-width: 36px;
--f7-sortable-sorting-item-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.6);
}
.md {
--f7-sortable-handler-width: 42px;
--f7-sortable-sorting-item-box-shadow: var(--f7-elevation-2);
}
.aurora {
--f7-sortable-handler-width: 32px;
--f7-sortable-sorting-item-box-shadow: var(--f7-elevation-2);
}
Examples
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="left"></div>
<div class="title">Sortable</div>
<div class="right">
<!-- Link to toggle sortable -->
<a class="link sortable-toggle" data-sortable=".sortable">Toggle</a>
</div>
</div>
</div>
<div class="page-content">
<div class="list sortable">
<ul>
<li>
<div class="item-content">
<div class="item-media"><i class="icon icon-f7"></i></div>
<div class="item-inner">
<div class="item-title">1 Jenna Smith</div>
<div class="item-after">CEO</div>
</div>
</div>
<div class="sortable-handler"></div>
</li>
<li>
<div class="item-content">
<div class="item-media"><i class="icon icon-f7"></i></div>
<div class="item-inner">
<div class="item-title">2 John Doe</div>
<div class="item-after">Director</div>
</div>
</div>
<div class="sortable-handler"></div>
</li>
...
</ul>
</div>
<div class="list media-list sortable">
<ul>
<li>
<div class="item-content">
<div class="item-media"><img src="https://cdn.framework7.io/placeholder/people-160x160-1.jpg" width="80"/></div>
<div class="item-inner">
<div class="item-title-row">
<div class="item-title">Yellow Submarine</div>
<div class="item-after">$15</div>
</div>
<div class="item-subtitle">Beatles</div>
<div class="item-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sagittis tellus ut turpis condimentum, ut dignissim lacus tincidunt. Cras dolor metus, ultrices condimentum sodales sit amet, pharetra sodales eros. Phasellus vel felis tellus. Mauris rutrum ligula nec dapibus feugiat. In vel dui laoreet, commodo augue id, pulvinar lacus.</div>
</div>
</div>
<div class="sortable-handler"></div>
</li>
...
</ul>
</div>
<div class="block-title">Opposite Side</div>
<div class="list sortable sortable-opposite">
<ul>
<li>
<div class="item-content">
<div class="item-media"><i class="icon icon-f7"></i></div>
<div class="item-inner">
<div class="item-title">1 Jenna Smith</div>
<div class="item-after">CEO</div>
</div>
</div>
<div class="sortable-handler"></div>
</li>
...
</ul>
</div>
</div>
</div>
var app = new Framework7();
app.on('sortableSort', function (listEl, indexes) {
console.log(indexes);
})