プログラミング

【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を使ったフレキシブルな「移動式マルチプルフォームの作り方」をご紹介しました。

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

     

    注目の記事

    HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44
    プログラミング
    PHP,PHPポケモン,ポケモン
    HPバーアニメーション 後編 フロント側の対応 PHPポケモン 44

    HPバーアニメーション それでは前回に続き、HPバーのアニメーションづくりをしていきましょう。前回、メッセージに合わせてレスポンスを返却するというサーバー側の仕組みを作成しました。なので、今回はそれをフロント側で受け取り、タイミングよくアニメーションで再現します。   フロント側(js)の処理 前回...

    たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは
    マーケティング
    コロナ,フリーランス,ホームページ制作,助成金
    たった2日で200万円!フリーランスが簡単に仕事を受注できる方法とは

      仕事の依頼が全然来ない・・・ 営業しても話を聞いてくれない・・・   その多くが営業力以上に、営業をすべきタイミングがわかっていない人がほとんどです。 実は助成金等を活用することで、行政書士などの職業以外でも仕事を受注することは可能になります。   今回は筆者が、たった2日で200万...

    トレーナー戦編 バトルシステムへの追加 PHPポケモン 98
    プログラミング
    PHP,PHPポケモン,ポケモン
    トレーナー戦編 バトルシステムへの追加 PHPポケモン 98

    トレーナー戦闘の追加 前回トレーナー情報を作成したので、今回はその情報をバトルシステムへ組み込んでいきます。 現在、野生ポケモンとの戦闘では「battle」という値actionの値で受け取っています。同じサービス内で分岐を作ると複雑になってしまうので、battle_trainerという新しい分岐を使ってサービス分けをし...

    事業所検索サービス「児発ねっと」児童発達支援・放課後等デイサービス
    ビジネスモデル
    SEO対策,プログラミング,児童デイサービス,児童発達支援,放課後等デイサービス
    事業所検索サービス「児発ねっと」児童発達支援・放課後等デイサービス

    どうも、児発ねっとの中の人です。 この度は児童発達支援・放課後等デイサービスといった療育施設の事業所検索サービス「児発ねっと」を開始することになりました。 本ブログでは、プログラミングやデザインといった内容のコンテンツを紹介しているため、児発ねっとのサービスは少し異色になります。なので、今回...

    なぜ、お金を配るの?悪質メール・SNSを利用した詐欺的手法への対処法とは
    ネットワーク
    amazon,SNS,Twitter,お金配り,楽天,迷惑メール
    なぜ、お金を配るの?悪質メール・SNSを利用した詐欺的手法への対処法とは

    定期的に書きたくなるコラムのコーナー! 今回は、迷惑メールやSNSのDMを活用した悪質な勧誘、巷で流行っているお金配りを隠れ蓑のした巧妙な詐欺的手法などをいくつかご紹介、その対策・リクス回避の方法をまとめました。   まず結論からお伝えすると 「怪しいと思うなら手を出すな」 です。その詳細を知りたい...

    たった10分!?読むだけでプログラミングが上達する3原則
    プログラミング
    jQuery,プログラミング学習,初心者
    たった10分!?読むだけでプログラミングが上達する3原則

      プログラミングがなかなか身につかない   学習をしているけど、自分で書くとなれば思うようにいかなかったり、覚えたはずなのにその使い方や応用方法がわからない人のほとんどが、作り方そのものが間違っている傾向にあります。   今回は、プログラミング初学者や、なかなかスキルアップができない人...

    人員配置計算機〜放課後等デイサービス・児童発達支援〜
    プログラミング
    JavaScript,児童デイ,児童発達支援,放課後等デイサービス,福祉,計算機
    人員配置計算機〜放課後等デイサービス・児童発達支援〜

    最近はずっとPHPポケモン開発にかかりっきりでしたが、そろそろ「役立つもの」を作りたくなったので、思いつきで作ってみました。 もちろん「汎用性」のあるものは、既に世の中に存在しているため、ありそうでなさそうなニッチなものを攻めてみます。   そんな中、今回挑んだのは「人員配置計算機」です。 ※実際に...

    オウムがえし編 PHPポケモン 68
    プログラミング
    PHP,PHPポケモン,ポケモン
    オウムがえし編 PHPポケモン 68

    オウムがえしとは 今回は久々に新しい技を実装します。それが「オウムがえし」です。 オウムがえし(ポケモンwiki) https://wiki.ポケモン.com/wiki/オウムがえし   初代で登場した技であり、序盤に登場するポッポやオニスズメがレベルアップで覚える技の1つです。最新世代ではオウムがえしという技は実...

    カテゴリ

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

    タグ

    5G Adobe AfterEffects AI ajax amazon Animate api artisan atom Automator AWS Bluetooth CSS CVR description EC-CUBE4 ECショップ ESLint Facebook feedly foreach function Google Google AdSense Honeycode htaccess HTML IEEE 802.11ax Illustrator Instagram IoT JavaScript 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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力