●Sortable.jsとは
Webサイトやアプリケーションでリストの項目を直感的に並び替えられたら便利ですよね。
そんな機能を簡単に実装できるのがSortable.jsです。
Sortable.jsは、ドラッグ&ドロップでリストの項目を自由に並び替えられるJavaScriptライブラリで、シンプルなAPIとわかりやすいコードが特徴です。
jQueryに依存せず、軽量で高速に動作するのもメリットの一つ。
○Sortable.jsの最大の特徴
Sortable.jsは、リストやグリッドの要素をドラッグ&ドロップで直感的に並び替えられるのが最大の特徴です。
マウスやタッチ操作に対応しており、PCでもスマートフォンでもストレスなく利用できます。
また、アニメーション効果を加えたり、ドラッグ中の要素のスタイルを変更したりと、柔軟なカスタマイズが可能。
他のライブラリとの競合も少なく、プロジェクトに組み込みやすいのも魅力ですね。
○Sortable.jsのインストール方法
Sortable.jsを利用するには、公式サイトからファイルをダウンロードするか、npmやyarnなどのパッケージマネージャを使ってインストールします。
CDNを利用する方法もあります。
必要なファイルを読み込んだら、あとはHTMLにソート対象の要素を記述するだけ。
とてもシンプルで導入のハードルが低いのがうれしいポイントです。
○サンプルコード1:基本的な使い方
早速、Sortable.jsの基本的な使い方を見ていきましょう。
まずはHTMLでソートしたいリストを用意します。
<ul id="my-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
次にJavaScriptでSortableを初期化します。
const list = document.getElementById('my-list');
new Sortable(list);
これだけでドラッグ&ドロップでの並び替えが可能になります。
シンプルですが、Sortable.jsの基本をしっかり押さえておきましょう。
●jQueryでSortable.jsを使う
バニラJavaScriptでSortable.jsを使うのも良いですが、jQueryと組み合わせると、より簡潔で読みやすいコードになります。
jQueryを使い慣れているエンジニアにとっては、導入のハードルがぐっと下がるでしょう。
ここではjQueryでSortable.jsを使う方法を、実践的なコードサンプルとともに解説していきます。
○jQueryでのSortable.jsの読み込み
jQueryでSortable.jsを使うには、まずjQueryとSortable.jsの両方を読み込む必要があります。
HTMLのheadタグ内やbodyタグの最後に、このようにscriptタグを記述します。
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
これでjQueryとSortable.jsが利用可能になります。
バージョンは適宜最新のものを指定してください。
○サンプルコード2:jQueryでのリスト並び替え
jQueryを使ってリストを並び替えるには、次のようなコードを記述します。
<ul id="my-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
$(function() {
new Sortable($('#my-list')[0]);
});
jQueryの$
関数を使ってリストの要素を取得し、それをSortableのコンストラクタに渡すだけです。
これでリストがドラッグ&ドロップで並び替えられるようになります。
シンプルですが、強力な機能ですよね。
○サンプルコード3:jQueryでのテーブル行のソート
Sortable.jsはテーブルのソートにも対応しています。
jQueryを使ってテーブルの行を並び替えるには、次のようなコードを書きます。
<table id="my-table">
<tbody>
<tr><td>Row 1</td><td>Data 1</td></tr>
<tr><td>Row 2</td><td>Data 2</td></tr>
<tr><td>Row 3</td><td>Data 3</td></tr>
<tr><td>Row 4</td><td>Data 4</td></tr>
</tbody>
</table>
$(function() {
new Sortable($('#my-table tbody')[0], {
animation: 150,
handle: 'td'
});
});
handle
オプションで、ドラッグ可能な要素をtdタグに限定しています。
これにより、テーブルのヘッダーをドラッグしても並び替えられないようになります。
animation
オプションでアニメーションの時間を指定し、スムーズな動きを実現。
jQueryとSortable.jsの組み合わせで、テーブルのソートも簡単に実装できました。
○サンプルコード4:jQueryでのテーブル列のソート
テーブルの行だけでなく、列のソートも可能です。
列を並び替えるには、次のようにコードを修正します。
$(function() {
new Sortable($('#my-table')[0], {
animation: 150,
handle: 'th',
direction: 'vertical'
});
});
direction
オプションで、縦方向のソートを指定します。
handle
オプションをthタグに変更し、テーブルのヘッダーをドラッグできるようにします。
あとはテーブルのHTML構造を列に合わせて修正するだけ。
jQueryとSortable.jsを使えば、テーブルの行と列、両方のソートが簡単に実現できます。
●バニラJavaScriptでSortable.jsを使う
素晴らしい、jQueryを使ったSortable.jsの実践例を見てきましたね。
ただ、「jQueryは使いたくない」「フレームワークに頼らずにJavaScriptでソートを実装したい」と思っている方もいるでしょう。
そんな方のために、ここからはバニラJavaScript(プレーンなJavaScript)でSortable.jsを使う方法をご紹介します。
フレームワークを使わずにJavaScriptでリッチなUIを実現するのは大変だと思うかもしれません。
でも、Sortable.jsを使えば、バニラJavaScriptでもドラッグ&ドロップによる直感的なソート機能が簡単に作れるんです。
jQueryに頼らずにJavaScriptの力だけでコーディングするのは、スキルアップにもつながりますよ。
○サンプルコード5:バニラJavaScriptでのリスト並び替え
まずは、バニラJavaScriptを使ってリストを並び替える方法から見ていきましょう。
HTMLはこのようになります。
<ul id="my-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
そして、JavaScriptでSortable.jsを初期化します。
const list = document.getElementById('my-list');
new Sortable(list);
document.getElementById
を使って、ソートしたいリストの要素を取得するだけ。
あとはjQueryの時と同じように、Sortableのコンストラクタに渡すだけで、リストがドラッグ&ドロップで並び替えられるようになります。
バニラJavaScriptでもこんなにシンプルに書けるんですね。
○サンプルコード6:バニラJavaScriptでのテーブルソート
リストだけでなく、テーブルのソートもバニラJavaScriptで実装できます。
HTMLは次のようなテーブルを用意します。
<table id="my-table">
<thead>
<tr><th>Name</th><th>Age</th><th>City</th></tr>
</thead>
<tbody>
<tr><td>John</td><td>25</td><td>New York</td></tr>
<tr><td>Alice</td><td>30</td><td>London</td></tr>
<tr><td>Bob</td><td>20</td><td>Paris</td></tr>
</tbody>
</table>
そして、JavaScriptでSortable.jsを初期化します。
const table = document.getElementById('my-table');
new Sortable(table, {
animation: 150,
handle: 'td, th',
direction: 'vertical'
});
テーブル要素を取得し、Sortableのオプションでhandle
とdirection
を指定するのはjQueryの時と同じ。
getElementById
を使えば、バニラJavaScriptでもテーブルのソートが実現できました。
フレームワークに頼らずにコーディングする面白さを感じますね。
○サンプルコード7:バニラJavaScriptでのマルチドラッグ
Sortable.jsには、複数の要素を同時にドラッグできる「マルチドラッグ」という便利な機能があります。
バニラJavaScriptでマルチドラッグを実装するには、このようなコードを書きます。
<ul id="my-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
const list = document.getElementById('my-list');
new Sortable(list, {
multiDrag: true,
selectedClass: 'selected',
onSelect: function(evt) {
console.log('Elements selected:', evt.items);
},
onDeselect: function(evt) {
console.log('Elements deselected:', evt.items);
}
});
multiDrag
オプションをtrue
にすると、Ctrlキーを押しながら複数の要素を選択できるようになります。
selectedClass
オプションで、選択中の要素に付与するCSSクラスを指定。
onSelect
とonDeselect
のコールバック関数で、要素の選択状態が変化した時の処理を記述できます。
バニラJavaScriptでも、Sortable.jsの高度な機能を存分に活用できます。
●Sortable.jsのオプション解説
バニラJavaScriptでのSortable.jsの使い方が理解できたところで、オプションを使ったカスタマイズ方法を見ていきましょう。
Sortable.jsにはドラッグ&ドロップの動作をコントロールするためのオプションが豊富に用意されています。
このオプションを活用することで、より使いやすく視覚的に優れたUIを実現できるのです。
Sortable.jsのオプションを使いこなせば、ドラッグ&ドロップ機能をアプリの要件に合わせて細かくチューニングできます。
ここでは、よく使われるオプションをピックアップして解説しますね。
○ドラッグ中の要素のスタイル変更
ドラッグ中の要素のスタイルを変更するには、ghostClass
オプションを使います。
new Sortable(list, {
ghostClass: 'sortable-ghost',
// ...
});
.sortable-ghost {
opacity: 0.5;
background-color: #F7F7F7;
}
ドラッグ中の要素にsortable-ghost
クラスが付与されるので、CSSでスタイルを定義します。
半透明にしたり、背景色を変えたりと、自由にカスタマイズできますよ。
○アニメーション効果の追加
ドラッグ&ドロップ時のアニメーションを追加するには、animation
オプションを使います。
new Sortable(list, {
animation: 150,
// ...
});
animation
オプションにはミリ秒単位でアニメーションの時間を指定します。
適度なアニメーションがあると、ドラッグ&ドロップの操作感が向上しますね。
○ドラッグ可能な要素の制限
特定の要素だけをドラッグ可能にするには、draggable
オプションを使います。
new Sortable(list, {
draggable: '.draggable',
// ...
});
<ul id="my-list">
<li class="draggable">Item 1</li>
<li>Item 2</li>
<li class="draggable">Item 3</li>
<li>Item 4</li>
</ul>
draggable
オプションにセレクタを指定することで、そのセレクタに一致する要素だけがドラッグ可能になります。
リスト内の一部の項目のみを移動させたい場合などに便利です。
○サンプルコード8:オプションを使ったカスタマイズ例
それでは、これまで紹介したオプションを組み合わせて、リッチなドラッグ&ドロップUIを作ってみましょう。
<ul id="my-list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
new Sortable(document.getElementById('my-list'), {
animation: 200,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag',
onChoose: function(evt) {
evt.item.classList.add('chosen');
},
onUnchoose: function(evt) {
evt.item.classList.remove('chosen');
},
onStart: function(evt) {
evt.item.classList.add('dragging');
},
onEnd: function(evt) {
evt.item.classList.remove('dragging');
},
});
.sortable-ghost {
opacity: 0.5;
}
.sortable-chosen {
background-color: #F7F7F7;
}
.sortable-drag {
opacity: 1;
}
.chosen {
color: #CCC;
}
.dragging {
background-color: #FFF;
}
ドラッグ中の要素のスタイルを変更し、アニメーションを追加。
さらに、選択中や操作中の要素にクラスを付与して、状態に応じたスタイルを適用しています。
コールバック関数を使って、よりインタラクティブなUIを実現しています。
●よくあるエラーと対処法
せっかくSortable.jsを導入しても、期待通りに動かないと困りますよね。
でも安心してください。
ほとんどの問題は簡単に解決できます。
一緒にエラーの原因と対処法を確認していきましょう。
○Sortable.jsが動作しない場合の確認点
Sortable.jsが動作しない原因として、JavaScriptファイルの読み込みミスが考えられます。
次の点を確認してみてください。
- HTMLでSortable.jsのファイルを正しく読み込んでいるか
- JavaScriptでSortableを初期化する際、セレクタが間違っていないか
- コンソールにエラーが出力されていないか
- これらを確認することで、多くの場合問題を特定できます。
また、jQueryと一緒に使う場合は、jQueryを先に読み込む必要があります。
HTMLでの読み込み順序に注意しましょう。
○ドラッグ&ドロップがずれる問題の解決策
ドラッグ&ドロップの挙動がおかしい場合、CSSが原因であることが多いです。
特に、要素のmargin
やpadding
、position
などのプロパティが影響することがあります。
.sortable-item {
margin: 0;
padding: 0;
position: relative;
}
要素間の余白を削除し、position
をrelative
に設定することで、ずれを解消できるかもしれません。
○ネストしたリストのソートがうまくいかない場合
リストの中にさらにリストがあるようなネストした構造の場合、親リストと子リストでSortableを別々に初期化する必要があります。
次のようなHTMLの場合を考えてみましょう。
<ul id="parent-list">
<li>Item 1</li>
<li>
Item 2
<ul id="child-list">
<li>Child Item 1</li>
<li>Child Item 2</li>
</ul>
</li>
</ul>
このような構造の場合、このようにSortableを初期化します。
new Sortable(document.getElementById('parent-list'), {
group: 'parent',
// ...
});
new Sortable(document.getElementById('child-list'), {
group: 'child',
// ...
});
親リストと子リストでグループを分けることで、それぞれ独立したソートが可能になります。
ネストしたリストをソートする場合は、構造に合わせてSortableを適切に初期化することが大切です。
●Sortable.jsの応用例
Sortable.jsの基本的な使い方はマスターできましたね。
でも、現代のWebアプリケーション開発では、Vue.jsやReactなどのフレームワークを使うことが主流になっています。
そこで、ここではSortable.jsをフレームワークと組み合わせる方法を見ていきましょう。
フレームワークを使った開発では、データとUIを分離し、コンポーネント単位で機能を実装するのが一般的です。
Sortable.jsをうまく組み込めば、リアクティブなドラッグ&ドロップ機能を実現できるはずです。
一緒にコードを見ながら、応用方法を学んでいきましょう。
○サンプルコード9:Vue.jsと組み合わせた使用例
まずは、Vue.jsでSortable.jsを使う方法です。
<template>
<ul ref="list">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</ul>
</template>
<script>
import Sortable from 'sortablejs';
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
]
};
},
mounted() {
new Sortable(this.$refs.list, {
animation: 150,
onUpdate: (event) => {
const item = this.items.splice(event.oldIndex, 1)[0];
this.items.splice(event.newIndex, 0, item);
}
});
}
};
</script>
mounted
ライフサイクルフックでSortableを初期化し、onUpdate
コールバックで並び替え後のデータを更新しています。
Vue.jsのリアクティブシステムによって、UIが自動的に更新されるのがポイントです。
Vue.jsと組み合わせることで、宣言的なテンプレートと豊富なディレクティブを活用しながら、Sortable.jsの機能を利用できます。
○サンプルコード10:Reactと組み合わせた使用例
続いて、ReactでSortable.jsを使う例を見てみましょう。
import React, { useRef, useEffect } from 'react';
import Sortable from 'sortablejs';
const MyList = () => {
const listRef = useRef(null);
const items = [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
];
useEffect(() => {
new Sortable(listRef.current, {
animation: 150,
onUpdate: (event) => {
const item = items.splice(event.oldIndex, 1)[0];
items.splice(event.newIndex, 0, item);
}
});
}, []);
return (
<ul ref={listRef}>
{items.map((item) => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
};
export default MyList;
useRef
フックでリストの要素への参照を取得し、useEffect
フックでSortableを初期化します。
あとはVue.jsの例と同様に、onUpdate
コールバックでデータを更新するだけです。
ReactのFunctional Componentとフックを使えば、宣言的でリユーザブルなコンポーネントを作れます。
その中でSortable.jsを活用することで、高度なインタラクションを実現できるわけです。
□Sortable.jsをBootstrapと併用する方法
CSSフレームワークのBootstrapと一緒にSortable.jsを使う場合、少し注意が必要です。
Bootstrapのクラスを適用したリストに対してSortableを初期化すると、思わぬ動作をすることがあります。
次のようなHTMLを考えてみましょう。
<ul id="my-list" class="list-group">
<li class="list-group-item">Item 1</li>
<li class="list-group-item">Item 2</li>
<li class="list-group-item">Item 3</li>
</ul>
このリストにそのままSortableを適用すると、ドラッグ&ドロップ時にレイアウトが崩れてしまうかもしれません。
そんな時は、このようなCSSを追加してみてください。
.list-group-item {
position: relative;
z-index: 1;
}
.list-group-item:focus,
.list-group-item:active {
z-index: 2;
}
z-index
プロパティを調整することで、ドラッグ中の要素が他の要素の上に重なるようになります。
これでBootstrapのスタイルを保ったまま、Sortableを使えるはずです。
□Sortable.jsをWordPressに組み込む方法
WordPressのプラグインを開発する際にも、Sortable.jsは活用できます。
管理画面でカスタムフィールドの順番を並び替えられるようにしたいと思ったことはありませんか?
Sortable.jsを使えば、それが簡単に実現できます。
functions.phpに次のようなコードを追加してみましょう。
function my_plugin_enqueue_scripts() {
wp_enqueue_script( 'sortablejs', 'https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js', [], '1.14.0', true );
wp_enqueue_script( 'my-plugin-script', plugins_url( 'js/script.js', __FILE__ ), ['jquery', 'sortablejs'], '1.0.0', true );
}
add_action( 'admin_enqueue_scripts', 'my_plugin_enqueue_scripts' );
admin_enqueue_scripts
アクションを使って、管理画面でSortable.jsとカスタムスクリプトを読み込みます。
あとはjsファイルの中で、Sortableを初期化するだけです。
jQuery(function($) {
new Sortable(document.getElementById('my-list'), {
// オプションを指定
});
});
これで、WordPressの管理画面にドラッグ&ドロップでソートできるリストが実装できました。
プラグインの機能をより使いやすくするのに、Sortable.jsは最適なのです。
まとめ
Sortable.jsは、ドラッグ&ドロップでリストを並び替えるのに最適なJavaScriptライブラリです。
jQueryやバニラJavaScriptと組み合わせて使えるだけでなく、Vue.jsやReactなどのモダンなフレームワークとも相性抜群。
シンプルなAPIとわかりやすいコードで、初心者でも簡単に導入できるのが魅力ですね。
この記事では、Sortable.jsの基本的な使い方から、オプションを使ったカスタマイズ、よくあるエラーの対処法まで、実践的なコードサンプルとともに解説してきました。
ドラッグ&ドロップ機能の実装に悩んでいた方も、これでスッキリ解決できるはずです。
リストやテーブルのソートはもちろん、Vue.jsやReactと組み合わせたリアクティブなUIの構築、WordPressプラグインへの応用など、Sortable.jsの可能性は無限大。
今回紹介したサンプルコードを参考に、自分のプロジェクトにぜひ取り入れてみてください。
きっと開発の幅が広がるはずです。
Webアプリケーションにリッチなインタラクションを追加するのに、Sortable.jsほど手軽で強力なライブラリはないでしょう。
ドラッグ&ドロップでリストを自由に並び替える、そんな直感的なUIを実現するために、ぜひSortable.jsをマスターしてくださいね。