スマレジ開発ひよっこblog

株式会社スマレジの開発チームで働くデザイナーのブログ

 AngularJSメモ:ドラッグ操作で並び替えて保存 ①/2

こんばんは。スマレジ開発ひよっこブログの時間です。

今作っているアプリではJavaScriptフレームワークにAngularJSを使っています。
その中でパネルの並び順をドラッグ操作で変更して保存するという機能を作ったのでやり方をメモします。

情報共有と、説明してみることでなんとなく使っている用語の整理ができればと思って書きます。ゆっくりゆっくり進みます。

こんな感じのものができあがります↓

・ドラッグ&ドロップでリストを並び替えられる
・並び替えがパネルにも反映される
・並び替えた順番をcookieに保存できる


デモです

codepen.io

cookieの部分がデモ環境で上手く動いてくれず省いたので中途半端なデモになってしまいました。。
実際には、変更した並び順が画面リロード時にも保持されているイメージです。
さあ作ってみます。

ドラッグで並び替えられるリストをつくる


まずドラッグで並び替えをする部分ですが、
jQuerUI(jQueryベースのライブラリ)のSortableというのを使ったらいい感じにできるらしいと教えてもらいそれを使うことにしました。
今回はAngularJSを使用するという前提があったので、SortableをAngularでうまく動くようにしてくれているUI.Sortableというライブラリを使いました。

AngularJSのサブプロジェクト UI.Sortable
https://angular-ui.github.io/ui-sortable/

Gitのreadmeに使用例がいろいろ載っています。


ということで、

準備
jQueryjQuery UI、AngularJS、UI.Sortableを読み込んでおきます。
また、AngularJSでui.sortableのモジュールを呼び出しておきます。(デモのjavascript1行目)

次に、並び替えをしたい要素の親要素にui-sortableディレクティブを追加します。
※AngularJSでは、htmlの元々の属性(href とか)と同様にhtmlnのタグに追加することでいろいろな機能を提供してくれる独自の属性のようなものが用意されており、「ディレクティブ」と呼ぶようです。

ui-sortableの属性値には、オプションが設定できるので、ui-sortable="sortableOptions" としておいてコントローラーの方でオプションの配列を渡しています。
jQuery UIのsortableの全オプションが使えるとのことです。
※試したところ、最低限"items"のオプション(並び替えたいものが何の要素かの設定)はないとうまく動かないようでした。

こんな感じ
html
    <ul ui-sortable="sortableOptions">
        <li>1</li>
        <li>2</li>
        <li>3</li>
    </ul>

javaScript(AngularJSのコントローラー内)
    $scope.sortableOptions = {
        'items' : '> li',
    }

これだけでぐいぐい並び替られるリストが出来上がりました。
Sortableって便利ですね。

※ちなみにこのままだと、タッチデバイスでは動きません。jQuery UI Touch Punch というライブラリをいれるとスマホなどのタッチ操作にも対応できるようです。

並び替えをパネルに反映させる

今回は並び替えた順番を保存したり、他の要素の並び順に反映させたりしたいので続きをつくっていきます。
ここからAngularJSが活躍します。

やること
配列オブジェクトを作ってパネルの情報と順番をまとめます。(Panelsとしました)
その配列をng-sortableのモデルに指定します。
同じ配列を元にng-repeatディレクティブを使ってリスト部分とパネル部分をそれぞれ出力するようにします。

※ng-repeatは、指定した配列の内容を元に要素を繰り返してくれるディレクティブ。

こんな感じ
html:
    <ul ui-sortable="sortableOptions" ng-model="Panels">
        <li ng-repeat="panel in Panels" ng-bind="panel.panelName"></li>
    </ul>
    <div ng-repeat="panel in Panels" class="panel" ng-bind="panel.panelID"></div>


javaScript(AngularJSのコントローラー内):
    $scope.sortableOptions = {
        'items' : '> li',
    }
    $scope.Panels=[
        {panelID:'1',panelName:'Panel 1'},
        {panelID:'2',panelName:'Panel 2'},
        {panelID:'3',panelName:'Panel 3'},
    ];

これで、ぐいぐい並び替えられるリストと、それに連動して動くパネルができました!


②に続きます。

続きますと書いて続きが書けていない記事がありますが、

今回は3日以内のアップを目指しています。


[参考にしたページ]

[AngularJS] UI.Sortable を使ったドラッグ&ドロップ UI の構築

AngularJS $cookies

ウェブデザイナーがはじめるAngularJS:ngCookiesやngStorageを使ったCookieやlocalStorageへのアクセス