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:

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.

ParameterTypeDefaultDescription
moveElementsbooleantrue

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 data-sortable-move-elements="true" or data-sortable-move-elements="false" attribute to list element.

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

EventTargetDescription
sortable:enableSortable List<div class="list sortable">Event will be triggered when sortable mode is enabled
sortable:disableSortable List<div class="list sortable">Event will be triggered when sortable mode is disabled
sortable:sortList 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
sortable:moveList element<li>Event will be triggered on every list item move during sorting

App Instance Events

Sortable instance emit events on app instance.

EventTargetArgumentsDescription
sortableEnableapplistElEvent will be triggered when sortable mode is enabled
sortableDisableapplistElEvent will be triggered when sortable mode is disabled
sortableSortappitemEl, data, listElEvent 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
sortableMoveappitemEl, listElEvent will be triggered on every list item move during sorting

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

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 (preferred to link)

  • To disable sortable mode we need to add sortable-disable class to any HTML element (preferred to link)

  • To toggle sortable mode we need to add sortable-toggle class to any HTML element (preferred 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).

.ios {
  --f7-sortable-handler-width: 36px;
  --f7-sortable-sorting-item-box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.6);
  --f7-sortable-handler-color: rgba(0, 0, 0, 0.22);
  --f7-sortable-sorting-item-bg-color: rgba(255, 255, 255, 0.8);
}
.ios .dark,
.ios.dark {
  --f7-sortable-sorting-item-bg-color: rgba(50, 50, 50, 0.8);
  --f7-sortable-handler-color: rgba(255, 255, 255, 0.55);
}
.md {
  --f7-sortable-handler-width: 42px;
  --f7-sortable-sorting-item-box-shadow: none;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-sortable-handler-color: var(--f7-md-on-surface-variant);
  --f7-sortable-sorting-item-bg-color: var(--f7-md-surface-3);
}

Examples

sortable.html
<div class="page">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner sliding">
      <div class="title">Sortable List</div>
      <div class="right">
        <a class="link sortable-toggle" data-sortable=".sortable">Toggle</a>
      </div>
    </div>
  </div>
  <div class="page-content">
    <div class="block">
      <p>Just click "Toggle" button on navigation bar to enable sorting</p>
    </div>
    <div class="list list-strong-ios list-outline-ios list-dividers-ios 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>
        <li>
          <div class="item-content">
            <div class="item-media"><i class="icon icon-f7"></i></div>
            <div class="item-inner">
              <div class="item-title">3 John Doe</div>
              <div class="item-after">Developer</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">4 Aaron Darling</div>
              <div class="item-after">Manager</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">5 Calvin Johnson</div>
              <div class="item-after">Accounter</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">6 John Smith</div>
              <div class="item-after">SEO</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">7 Chloe</div>
              <div class="item-after">Manager</div>
            </div>
          </div>
          <div class="sortable-handler"></div>
        </li>
      </ul>
    </div>

    <div class="list list-strong-ios list-outline-ios list-dividers-ios 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>
        <li>
          <div class="item-content">
            <div class="item-media"><img src="https://cdn.framework7.io/placeholder/people-160x160-2.jpg" width="80" />
            </div>
            <div class="item-inner">
              <div class="item-title-row">
                <div class="item-title">Don't Stop Me Now</div>
                <div class="item-after">$22</div>
              </div>
              <div class="item-subtitle">Queen</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>
        <li>
          <div class="item-content">
            <div class="item-media"><img src="https://cdn.framework7.io/placeholder/people-160x160-3.jpg" width="80" />
            </div>
            <div class="item-inner">
              <div class="item-title-row">
                <div class="item-title">Billie Jean</div>
                <div class="item-after">$16</div>
              </div>
              <div class="item-subtitle">Michael Jackson</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 list-strong-ios list-outline-ios list-dividers-ios 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>
        <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>
        <li>
          <div class="item-content">
            <div class="item-media"><i class="icon icon-f7"></i></div>
            <div class="item-inner">
              <div class="item-title">3 John Doe</div>
              <div class="item-after">Developer</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">4 Aaron Darling</div>
              <div class="item-after">Manager</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">5 Calvin Johnson</div>
              <div class="item-after">Accounter</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">6 John Smith</div>
              <div class="item-after">SEO</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">7 Chloe</div>
              <div class="item-after">Manager</div>
            </div>
          </div>
          <div class="sortable-handler"></div>
        </li>
      </ul>
    </div>
  </div>
</div>