プログラミング

【jQuery】移動式マルチプルフォームの作り方【sortable】

HTML JavaScript jQuery jQuery UI
【jQuery】移動式マルチプルフォームの作り方【sortable】

     

    移動式マルチプルフォーム

     

     

    デモページ

     

    htmlの標準マルチプルフォームは、選択したものに色が付く仕様ですが、数が多くなってくると選択しているものがわかり難いということや、並び順の変更がしにくいという難点があります。そういった条件も込みで再現するような選択要素移動式のフォームをご紹介します。

     

    以下サンプルコードです。 

    <!-- head -->
    <script
    src="https://code.jquery.com/jquery-3.5.1.min.js"
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
    crossorigin="anonymous"></script>
    <script
    src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
    integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
    crossorigin="anonymous"></script>
    
    <style>
    form{
        max-width: 300px;
        margin-bottom: 16px;
    }
    .flexbox{
        display: flex;
        margin-bottom: 8px;
    }
    .box{
        margin: 0 8px;
    }
    .select-box{
        width: 150px;
        height: 200px;
        overflow-y: scroll;
        background-color: #DDD;
        padding: 4px;
    }
    .item{
        color: #FFF;
        background-color: #888;
        cursor: pointer;
    }
    .item:not(:last-child){
        margin-bottom: 4px;
    }
    .result{
        padding: 4px;
    }
    </style>
    <!-- body -->
    <form action="" method="post">
        <div class="flexbox">
            <div class="box">
                <span>未選択</span>
                <div class="select-box">
                    <div class="item" data-val="item1">
                        アイテム1
                    </div>
                    <div class="item" data-val="item2">
                        アイテム2
                    </div>
                    <div class="item" data-val="item3">
                        アイテム3
                    </div>
                </div>
            </div>
            <div class="box">
                <span>選択済み</span>
                <div class="select-box selected">
                </div>
            </div>
        </div>
        <input type="submit" value="送信">
    </form>
    
    <div class="result">
        <div class="box">
            <span>送信結果</span>
            <pre><?php var_export($_POST); ?></pre>
        </div>
    </div>
    
    <script type="text/javascript">
    $(document).ready(function() {
        $( ".select-box" ).sortable({
            connectWith: ".select-box"
        })
        .bind("sortremove", function(event, ui) {
            var obj = ui.item;
            if (obj.parent(".select-box").hasClass("selected")) {
                // 選択済みエリアに移動してきたらinputを付与
                var val = obj.data("val");
                obj.append(
                    '<input type="hidden" name="select[]" value="' + val + '">'
                );
            } else {
                // 未選択テーブルに移動してきたらinputを削除
                obj.find("input").remove();
            }
        });
    });
    </script>

     

     

    jQueryとUIの読み込み

     

    まずは必要ライブラリを読み込みます。今回はjQuery UIのsortableを使用するので、jQueryとjQuery UIが必要です。CDNでの読み込み方法は以下の通りです。

    <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>

     

     

    ブロック要素を使った構成

     

    まずはHTML部分から確認していきます。今回はdivを使って擬似的にマルチプル形式のフォームを作成しています

    まずはデータを飛ばすために、全体をform要素で囲っていますが、送信ボタンも含めて必要なエリアだけが囲えていれば問題ありません。

     

    マルチプル部分で重要なポイントは以下boxの下層部分です。 

    <div class="box">
        <span>未選択</span>
        <div class="select-box">
            <div class="item" data-val="item1">
                アイテム1
            </div>
            <div class="item" data-val="item2">
                アイテム2
            </div>
            <div class="item" data-val="item3">
                アイテム3
            </div>
        </div>
    </div>
    
    <div class="box">
        <span>選択済み</span>
        <div class="select-box selected">
        </div>
    </div>

     

    sortableで移動させる両エリアを判定するために、select-boxというクラスを指定しています。これはライブラリに依存している名称ではないので、自由に決めてもらって構いません。

    選択済みボックスには、それを判別できるように追加でselectedというクラスを付与しています。こちらも未選択との違いを判別できるのであれば名称は自由です。

    次に、itemについてです。これがselectボックスでのoptionの代わりの要素です。itemに付与しているデータ属性(data-val)は、本来optionに付与するvalueの代わりに使用しています。今回はアイテム1、2、3と準備したので、それぞれにitem123と命名しました。

    最後に送信ボタンを準備すれば、HTML部分は完了です。

     

     

    multipleを使用しない理由

     

    selectmultipleを使っても、左右間の移動は可能です。以下のサイトでその方法が紹介されています。

    ※他にも実用的な多くサンプルが紹介されているので、ぜひ参考にしてください

     

    並び順を重視しないのであれば、multipleフォームが使用できるため、データを送信するという点においてはsortableもつよう実装は簡単です。しかし、フレキシブルに送信データを決めることができないのが欠点です。

    また、行としてoptionを選択するため、マルチプルの場合は1行に複数要素を含めることが出来ませんdiv要素等で生成すれば、1行にidname、チェックの有無などを含めることが可能です。

     

     

    tableを使用しない理由

     

    tableを使えば、行づくりはより簡単に実装することが可能です。もし1行に複数要素を含めるとしても、より簡単に実装でき向いていると言えます。

    しかしtableで作成すると、選択済みボックスの方に問題が残ります。行がなければ高さが0になってしまうため、移動エリアが無くなってしまうのです。そうならないため、高さの指定ができるブロック要素であるdivを採用しました。

     

     

    動的なinput要素

     

    div要素で構成している以上、データを送信するためにはinput要素を準備しなければなりません。しかし、最初からinput要素をアイテム内に配置してしまえば、未選択データもPOSTすることになります。そうならないためにも、sortableで移動した先が選択済みかどうかを判定して、input hiddenを追加します。

     

    それでは、sortableの内容と合わせて確認してみましょう。

    $( ".select-box" ).sortable({
        connectWith: ".select-box"
    })

     

    まずは、sortableの宣言です。select-boxのクラスに対してメソッドをつなげています。sortableのオプションには、connectWith指定しています。ここにselect-boxを宣言することで、全てのselect-box内で要素の移動ができるようになっています。

     

    次に要素移動時の処理をsortableにつなげます。

    .bind("sortremove", function(event, ui) {
        var obj = ui.item;
        if (obj.parent(".select-box").hasClass("selected")) {
            // 選択済みエリアに移動してきたらinputを付与
            var val = obj.data("val");
            obj.append(
                '<input type="hidden" name="select[]" value="' + val + '">'
            );
        } else {
            // 未選択テーブルに移動してきたらinputを削除
            obj.find("input").remove();
        }
    });

     

    そのままbindのメソッドをつなげて、sortremoveでコールバック関数を指定しています。この関数内に移動後の処理を記述していきます。

     

    ui.itemには移動してきたアイテム(class=”item”)が該当します。移動後、そのアイテムが未選択エリアにいるのか、選択済みエリアにいるかを確認するため、条件分岐でselect-boxの要素にselectedクラスが含まれているかをhasClass(“selected”)でチェックします。

    もし、selectedのエリアに移動してきたのであれば、input要素を付与します。 

    // 選択済みエリアに移動してきたらinputを付与
    var val = obj.data("val");
    obj.append(
        '<input type="hidden" name="select[]" value="' + val + '">'
    );

     

    ここで使用するのが、data-valです。これをdata(“val”)で取得して、アイテム要素の後ろにappendhiddenで追加します。これで、選択済みエリアに移動すればinput要素が付与されているため、データを送信することができます。

    もし一度選択済みエリアへ移動して、未選択エリアに戻ってきた場合はinput要素は不要です。そのため、条件分岐でのelse内にinput要素を取り除く記述を追加します。

    // 未選択テーブルに移動してきたらinputを削除
    obj.find("input").remove();

     

    これで、左右移動型疑似マルチプルフォームが完成です。

    デモページ 

     

     

    配列での送信

     

    最後に送信データの形式についてです。

    疑似ではありますが、multipleで送られてきたデータがバラバラになっていると処理をしづらくなります。そうならないためにも、input要素は配列として受け渡します。

    name="select[]"

     

    こうすることで、POSTすればselect内に選択済みの要素が上から順番に格納されます。

    # 送信結果
    array (
      'select' =>
      array (
        0 => 'item2',
        1 => 'item1',
      ),
    )

     

    もし1行に複数要素を含めて送信する場合も、配列として管理するようにしましょう。そうすれば受け取り側の処理も簡単になります。

     

     

    まとめ

     

    いかがだったでしょうか。

    今回はjQuery UIsortableを使ったフレキシブルな「移動式マルチプルフォームの作り方」をご紹介しました。

    複雑なデータ登録をする際には非常に役立つ方法ですので、システム要素の強いフォームや、直感的で使いやすいフォームを実装したいと考えている方は、ぜひ参考にしてくださいね。

     

    注目の記事

    フリーランスになるなら知っておきたい!無料サービス3選
    フリーランス
    フリーランスになるなら知っておきたい!無料サービス3選

      「フリーランスになる前に何を準備すればいいの?」 「フリーランス向けの便利なサービスが知りたい」   今回はそんな悩みを抱えた人へ向けて「フリーランスになるなら知っておきたい!無料サービス3選」をご紹介します。 この記事を読んで、フリーランスにとっての悩みである以下の3つの問題を一緒...

    ピカチュウから学ぶオブジェクト指向 〜レベルシステム導入編〜 3
    プログラミング
    PHP,PHPポケモン,オブジェクト指向,ポケモン
    ピカチュウから学ぶオブジェクト指向 〜レベルシステム導入編〜 3

      大人気?シリーズ「ピカチュウから学ぶオブジェクト指向」、今回はレベルシステムの導入編です。   第1回(基礎編)、第2回(クラス継承編)で作成したPokemonとPikachuのクラスを使用するので、最初から学習したい人はぜひご参考ください。      レベルシステムの導入   ポケモンのゲ...

    ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか
    プログラミング
    amazon,AWS,Honeycode,NoCode,プログラミング学習
    ノーコード開発で将来プログラミングは不要?我々は何を学ぶべきなのか

      近年、プログラミングの需要は増え勢いを増していますが、それ以上にノーコードというソースコードを打たなくでもアプリ開発ができるというソフトウェアやプラットフォームが普及してきました。 これにより一部の期待感とは別に、プログラマーという職業は今後不要になるのではないかと危機感を抱く人が出て...

    名刺は時代遅れ!?Googleの名刺検索「ピープルカード」とは
    フリーランス
    Google,SEO
    名刺は時代遅れ!?Googleの名刺検索「ピープルカード」とは

      Googleが2020年8月よりインドでピープルカードの検索機能を開始しました。これがフリーランスや個人事業主、起業家などに対して営業ツールとして大きな影響をもたらすのでは無いかと期待されており、今後ビジネスにおける繋がりが大きく変化していくことも予想されます。   今回は、そんなGoogleの新し...

    捕獲処理実装編 PHPポケモン 80
    プログラミング
    PHP,PHPポケモン,ポケモン
    捕獲処理実装編 PHPポケモン 80

    捕獲処理の作成 前回モンスターボールのクラスを作成したので、今回は捕獲判定までの一連の処理を仕上げていきます。サービス自体は他のアイテムと一緒にするためItemServiceを呼び出し、その中で使用されたアイテムを判断して分岐を作ります。   バトル中のアイテムサービス(/App/Services/Battle/ItemService.ph...

    ピカチュウから学ぶオブジェクト指向 〜レベルアップ編〜 5
    プログラミング
    PHP,PHPポケモン,オブジェクト指向,ポケモン
    ピカチュウから学ぶオブジェクト指向 〜レベルアップ編〜 5

      第3回でレベルシステムを導入し、第4回では経験値システムの導入をしたので、今回はそれを合わせたレベルアップのシステムを導入します。 第1回から作成しているコードを使用しているので、もし最初から学習したい人は第1回の入門編をご覧ください。     レベルアップシステムの導入   レベル...

    PHPポケモン「コントローラー編」〜POSTとSESSIONの活用〜 10
    プログラミング
    PHP,PHPポケモン,ポケモン
    PHPポケモン「コントローラー編」〜POSTとSESSIONの活用〜 10

      今回のPHPポケモンでは、今まで作った機能用のコントローラーになるインターフェースを作成します。ポケモンやメソッドを選択できるようにして、よりゲーム性の高いアプリケーションを実装しましょう。   第1回から学習したい方はコチラ     コントローラーの実装   それでは実装したアクション...

    プレイヤー情報作成編 PHPポケモン72
    プログラミング
    PHP,PHPポケモン,ポケモン
    プレイヤー情報作成編 PHPポケモン72

    プレイヤー情報の作成 少し前よりプレイヤーをホーム画面に表示させるようにしましたが、ただイメージとして配置しただけでプレイヤー情報自体は設定していませんでした。なので、今回はプレイヤーとして持たせる必要のある情報を作成していきましょう。   クラスの作成 初代ポケモンではプレイヤー情報として閲...

    カテゴリ

    SEO対策 イベント デザイン ネットワーク ビジネスモデル フリーランス プログラミング マーケティング ライティング 動画編集 雑記

    タグ

    5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach fortify function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript jetstream jQuery jQuery UI keyword LAN Laravel Linux MacBook MAMP meta MLM MySQL NoCode note OS OSI参照モデル Paypal Photoshop PHP phpMyAdmin PHPポケモン PremierePro rss SEO SEO対策 Sequel Pro Skype SNS SSH Symfony TCP/IP title Toastr Trait Twig Twitter UCC V系 WAN WebSub Wi-Fi wiki Windows WordPress XAMPP xml Xserver YouTube YouTuber Zoom アーティスト アウトプット アクセス層 アニメーション アフィリエイト イーブイ インターネット インプット エンジニア オブジェクト指向 お金配り クリック単価 クリック数 コミュニケーション能力 コロナ コンサルティング サムネイル システムエンジニア スタートアップ スタイルシート スパム データベース ディープフェイク デザイナー デザイン テレワーク ナンパ ニュース ネットワークモデル ノマドワーク バナー ピカチュウ ビジネス フィード フリーランス ブロガー ブログ プログラマー プログラミング プログラミング学習 プログラミング教育 プロトコル ホームページ制作 ポケモン マークアップ マーケティング メール リモートワーク レンダリング 三井住友 三宮 仕事依頼 児童デイ 児童デイサービス 児童発達支援 公開鍵 初心者 助成金 勉強法 営業 広告 広告収入 必勝マニュアル 放課後等デイサービス 朝活 楽天 深層学習 無線LAN 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 認証 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力