スポンサー
Support Framework7

ソータブルリスト

    ソータブルリストは、リストビューの拡張機能で、リストビューの要素をソートすることができます。

    ソート可能なリストのレイアウト

    ここでは、リストビューにおけるソート可能なリストのレイアウト構造について説明します。

    <!-- リストブロックに "sortable "クラスを追加 -->
    <div class="list sortable">
        <li>
            <div class="item-content">
                <div class="item-media">...</div>
                <div class="item-inner">...</div>
            </div>
            <!-- ソート可能なハンドラ要素 -->
            <div class="sortable-handler"></div>
        </li>
        ...
    </div>

    構造

    • sortable-handler - 現在のリストビュー要素をソートするための「ドラッグ可能な」要素(デフォルトでは非表示)。

    ご覧のように非常にシンプルで、必要なのはリストブロックに sortable クラスを追加し、<div class="sortable-handler"></div><li> の直接の子として置くだけです。

    ソートの無効化

    特定のアイテムのソートを無効にする必要がある場合は、no-sortingdisallow-sortingクラスをアイテムに追加します。

    <!-- リストブロックに "sortable "クラスを追加 -->
    <div class="list sortable">
        <!-- このアイテムのソートを無効にする -->
        <li class="no-sorting">...</li>
    
        <!-- ソート可能なアイテム -->
        <li>...</li>
        <li>...</li>
    </div>

    注意していただきたいのは、この方法はリストの最初か最後のアイテムに対してのみ意味を持ち、動作するということです。もし、途中のアイテムに対してソートを無効にした場合、正しく動作しません。

    反対側の並べ替え

    ソート可能なハンドラを反対側に表示する必要がある場合(例えば、LTR方向で左に表示する場合)、ソート可能なリストに sortable-opposite を追加する必要があります。

    <!-- ソート可能なリストへの "sortable-opposite "クラスの追加 -->
    <div class="list sortable sortable-opposite">
      <li>
        <div class="item-content">
          <div class="item-media">...</div>
          <div class="item-inner">...</div>
        </div>
        <!-- ソート可能なハンドラ要素 -->
        <div class="sortable-handler"></div>
      </li>
      ...
    </div>
    

    ソート可能なアプリのメソッド

    ソート可能なリストでソートモードを有効/無効にするには、以下のアプリのメソッドを使用します。

    app.sortable.enable(listEl)- ソート可能なリストでソートモードを有効にする

    • listEl - HTMLElementまたはstring(CSS Selectorを使用)。ソート可能なリストブロック要素。

    app.sortable.disable(listEl)- ソート可能なリストのソートモードを無効にする

    • listEl - HTMLElement または string (with CSS Selector). ソート可能なリストのブロック要素。

    app.sortable.toggle(listEl)- ソート可能なリストのソートモードを切り替える

    • listEl - HTMLElement または string (with CSS Selector). ソート可能なリストのブロック要素。

    ソータブルアプリのパラメータ

    アプリの初期化時に、sortableプロパティにソート可能な関連パラメータを渡すことで、グローバルなソートの動作を設定することができます。

    ParameterTypeDefaultDescription
    moveElementsbooleantrue

    これを有効にすると、ソート可能な新しい順序に従って、HTML要素が移動(並び替え)されます。ReactやVueなど、DOMを操作する他のライブラリを使っている場合は、この機能を無効にすると便利です。

    また、リスト要素に data-sortable-move-elements="true" または data-sortable-move-elements="false" 属性を追加することで、特定のリストに対してこの動作を上書きすることができます。

    これらのパラメータを変更するには、アプリの起動時に sortable プロパティで渡す必要があります。

    var app = new Framework7({
      sortable: {
        moveElements: false
      }
    });
    

    ソート可能なイベント

    sortableは、sortableリストブロック要素に対して以下のDOMイベントを実行し、アプリのインスタンスに対してイベントを実行します。

    DOMイベント

    EventTargetDescription
    sortable:enableSortable List<div class="list sortable">イベントは、Sortable モードが有効なときに発生します。
    sortable:disableSortable List<div class="list sortable">イベントは、Sortable モードが無効になったときに発生します。
    sortable:sortList element<li>イベントは、ユーザーが現在のソート要素を新しい位置にリリースした後に発生します。event.detail には、ソートされたリストアイテムの from/to インデックス番号を持つ from および to プロパティと、ソートされた HTML 要素を持つ el` プロパティを持つオブジェクトが含まれます。

    アプリのインスタンスイベント

    ソート可能なインスタンスは、アプリのインスタンス上でイベントを発行します。

    EventTargetArgumentsDescription
    sortableEnableapplistElソート可能なモードが有効になると、イベントが発生します。
    sortableDisableapplistElソート可能なモードが無効になると、イベントが発生します。
    sortableSortapplistEl, dataイベントは、現在ソートされている要素をユーザが新しい位置にリリースした後に発生します。data はオブジェクトで、fromto` プロパティには、ソートされたリストアイテムの from/to インデックス番号が入ります。

    ソート可能なオンタップホールド

    ソート可能/不可能のロジックを回避して、アイテムのタップ&ホールド(長押し)でリストアイテムをソート可能にすることができます。これを実現するには、ソート可能なリストに sortable-tap-hold クラスを追加する必要があります。

    <!-- ソート可能なリストに "sortable-tap-hold "クラスを追加する -->
    <div class="list sortable sortable-tap-hold">
      ...
    </div>

    この場合、アプリはカスタムの taphold イベントに依存します。正しく動作させるためには、app parameterで、touch.tapHold: trueも有効にしてください。

    リンクによるソートの制御

    リンクの特殊なクラスやデータ属性を使って、ソート可能なモードを有効にしたり無効にしたりすることができます。

    • ソート可能なモードを有効にするには、任意のHTML要素(リンクが望ましい)にsortable-enableクラスを追加する必要があります。

    • ソート可能なモードを無効にするには、任意の HTML 要素(リンクが望ましい)に sortable-disable クラスを追加する必要があります。

    • ソート可能なモードを切り替えるには、任意の HTML 要素に sortable-toggle クラスを追加する必要があります (リンクが望まれます)。

    • アプリ内に複数のソート可能なリストがある場合は、必要なソート可能なリストの CSS セレクタを持つ HTML 要素に data-sortable=".sortable" 属性を追加して、適切なソート可能なリストを指定する必要があります。

    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: 42px;
      --f7-sortable-sorting-item-box-shadow: var(--f7-elevation-2);
    }
    

    Examples

    <template>
      <div class="page">
        <div class="navbar">
          <div class="navbar-bg"></div>
          <div class="navbar-inner">
            <div class="title">Sortable</div>
            <div class="right"><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>
              <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 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 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>
    </template>
    <style>
      .icon-f7 {
        background: #EE350F;
        color: #fff !important;
        border-radius: 50%;
        text-align: center;
      }
    
      .icon-f7:before {
        content: '7';
      }
    
      .ios .icon-f7 {
        width: 29px;
        height: 29px;
        line-height: 29px;
      }
    
      .md .icon-f7 {
        width: 24px;
        height: 24px;
        line-height: 24px;
      }
    </style>
    <script>
      export default (props, { $f7 }) => {
        $f7.on('sortableSort', function (listEl, indexes) {
          console.log(indexes);
        });
    
        return $render;
      }
    </script>