プログラミング

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

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

     

    注目の記事

    バーアニメーションの不具合対応編 PHPポケモン 54
    プログラミング
    PHP,PHPポケモン,ポケモン
    バーアニメーションの不具合対応編 PHPポケモン 54

    最近は細々した対応が多くて「早く次のステップに進めよ!」と思っている方も多いでしょう。 ご意見ごもっともですが、残っている対応が意外にも追加しなければいけない処理が多く苦戦しているのが実情だったりします。そして、そのおかげか試行回数が多くなり見過ごしていた不具合や修正不備がポロポロ出てきていま...

    自称デザイナーがおしゃれ名刺を作成してみた!2度見したくなる名刺とは?
    デザイン
    Adobe,Illustrator
    自称デザイナーがおしゃれ名刺を作成してみた!2度見したくなる名刺とは?

      自称デザイナーらしく、オリジナルデザインの名刺を作成しました。 今回作った名刺はコチラです。   会社名や住所、名前の部分は仮で当てはめています。公開情報なのでそのままでも良いんですが一応です。   今回は「自称デザイナーがおしゃれ名刺を作成してみた!2度見したくなる名刺とは?」につい...

    バズる!ビジネスの見つけ方 〜何で起業するか悩んでいませんか?〜
    マーケティング
    ビジネス,起業
    バズる!ビジネスの見つけ方 〜何で起業するか悩んでいませんか?〜

      独立や起業を志している9割以上の人が「何をビジネスにするか?」を悩んでいます しかし、それは負のサイクルです。 起業するためにビジネスを考えるという行為自体が”矛盾している”ということに気づかなければ、このサイクルからは抜け出すことができません。 その結果、行動できずに終わってしまう人は多...

    Laravel7系でTraitのmakeコマンドを作成する方法
    プログラミング
    artisan,Laravel,Linux,PHP,Trait
    Laravel7系でTraitのmakeコマンドを作成する方法

    Laravel7がリリースされて、さっそくそれを使った開発の機会がやってきましたので、使用頻度の高いものをまとめていきたいと思います。 5系や6系の情報は多く出回っていますが、6系がLTSということもあって7系の情報は少なめですね。   今回は「Laravel7系でTraitのmakeコマンドを作成する方法」をご紹介します...

    投稿タイトルを自動生成する方法【WordPressを便利にカスタマイズ】
    プログラミング
    PHP,WordPress
    投稿タイトルを自動生成する方法【WordPressを便利にカスタマイズ】

      カスタムフィールドを含む投稿の場合、わざわざタイトルを設定する必要がないものもあります。 そういったときに、カスタムフィールド値を使ってタイトルを自動生成してくれると楽ですし、一覧で見てもわかりやすい状態にすることができます。   今回はWordPressで「投稿タイトルを自動生成する方法」につ...

    SNSだけじゃダメ!PV数アップのためにSEO対策する理由とは
    SEO対策
    Twitter
    SNSだけじゃダメ!PV数アップのためにSEO対策する理由とは

      「SNSで集客しているけど中々伸びなくなってきた」 「たまにPV数がアップするけど安定しない」 「本当に月何十万も稼げるぐらいPVは伸びるの?」   PV数を稼ぐためにSNSを駆使したり、中には広告を使って集客しているサイトもあるでしょう。ですが、それだけでは疲弊しながらユーザーを獲得しているに...

    PHPポケモン(α)第1回目の大型アプデ
    プログラミング
    PHP,PHPポケモン,ポケモン
    PHPポケモン(α)第1回目の大型アプデ

    第1回目 大型アップデートについて 本日、PHPポケモンの大型アップデートをしました。 今回のアップデートには全体的なデザインチェンジが含まれているため、今まで遊んでくれていた人も、新鮮な気持ちで初められることができるはずです。   デザインについては、PHPを使った開発をしている人からすれば馴...

    フレンドリィショップ編 開店準備 PHPポケモン 75
    プログラミング
    PHP,PHPポケモン,ポケモン
    フレンドリィショップ編 開店準備 PHPポケモン 75

    アイテム(どうぐ) PHPポケモンもバトル機能が一通り揃ってきたので、新機能として「アイテム」の実装に取り掛かります。 アイテムにも色々ありますが、技やポケモンのクラス同様に、初代で登場したアイテムから順番に取り揃えていきましょう。   キズぐすりの実装 ポケモンのどうぐ、一番手は「キズぐすり」...

    カテゴリ

    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 独立 神戸 福祉 秘密鍵 翻訳 自己啓発 英語 見積書 計算機 読書 起業 迷惑メール 配列 銀の弾丸 集客 雑学力