プログラミング

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

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

     

    注目の記事

    V系バンド必見!?アーティスト衣装販売サービスは成功するか?【ビジネス企画書】
    ビジネスモデル
    ECショップ,V系,アーティスト,コンサルティング,スタートアップ
    V系バンド必見!?アーティスト衣装販売サービスは成功するか?【ビジネス企画書】

      この記事は、私の考えたビジネスモデルを紹介するコーナーです。考えるだけで辞めたものや、コストやリスクを考えて断念したもの、そこまでニーズがないと判断したものなど様々なので、読んだ方は自分なりの見解や根拠を踏まえて判断したり、各自ビジネスの参考資料としてご活用ください。   今回は...

    ブログ運営者のための「よくわかるSEO対策」フィード編
    SEO対策
    atom,feedly,rss,WebSub,WordPress,xml,フィード
    ブログ運営者のための「よくわかるSEO対策」フィード編

      アメブロやFC2など優れたブログサービスが存在している中、好きなデザイン、こだわった機能を求めてWordPressを選択される方も多いですね。 また、コーポレートサイトにWordPressを用いる方もいるでしょう。ただしSEO対策がしっかりとされていなければ、提供されているサービスに太刀打ちできません。  もちろん...

    PHPポケモン(α)攻略wiki「稼ぎ方特集」
    雑記
    PHP,PHPポケモン,ポケモン
    PHPポケモン(α)攻略wiki「稼ぎ方特集」

    前回に引き続き、連続wiki投稿でPHPポケモン溺愛ユーザーにとっては歓喜の2日間です。   という冗談も踏まえつつ、今回は「稼ぐ」ということについて真面目に考察してみたいと思います。もしリアル世界での「稼ぐ」を目的に来た人は、盛大にブラウザバックしてください。   PHPポケモンにおける「稼ぐ」...

    デザイン
    サムネイル,デザイナー,バナー,広告
    デザイナーにセンスは必要ない!誰でも作れるおしゃれなサムネイル

      「デザイナーになるためにはセンスが必要ですか?」   バナーづくりの小規模講習会を実施した際に、この質問した人がいました。 よくある質問なのですが、いつも決まって自分の回答は「NO」です。   実際に一流のデザイナーとして活躍するレベルまでいくには、確かにセンスと呼ばれているものが必要...

    ブラウザで遊べる「PHPポケモン」
    プログラミング
    PHP,PHPポケモン,ポケモン
    ブラウザで遊べる「PHPポケモン」

    PHPポケモン 約1ヶ月半をかけて作り込んできたPHPポケモンですが、ある程度遊べるぐらいのレベルになったので、みなさまにも体験・楽しんでいただけるよう本日(2020年10月12日)より一般公開します。   PHPポケモンへのリンクは本記事の最後に用意しておりますので、プレイする前に注意事項等に目を通し...

    WordPressで作ったサイトで実装するワンランク上のSEO対策
    SEO対策
    PHP,WordPress,プログラミング
    WordPressで作ったサイトで実装するワンランク上のSEO対策

      WordPressでSEOに強いサイトを運営したい   近年、ブログを採用せずともWordPressを使用したサイト作りが増えてきました。 その理由には更新の手軽さはもちろん、優秀なプラグインが揃っていることでSEO対策に強いサイト作りが簡単だということが大きいです。   今回は、WordPressのブログやサイトで役立...

    PHPポケモン「バトルシステム編〜状態異常2〜」31
    プログラミング
    PHP,PHPポケモン,ポケモン
    PHPポケモン「バトルシステム編〜状態異常2〜」31

      前回に引き続き、状態異常チェックを実装します。 まず、前回実装した「ねむり」の処理についてですが、やはりターン数をセットして経過ターン数を引いていくという処理の方が解除率もゲーム再現になるので、まず修正をしておきます。サーセン。   チェック格納トレイト(/Traits/Battle/CheckTrait.php) ...

    PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20
    プログラミング
    PHP,PHPポケモン,ポケモン
    PHPポケモン「バトルシステム実装編〜ダメージ計算〜」20

    バトルシステムの実装  今回はバトルシステムの中でもメインとなるダメージ計算と、命中判定の部分を実装していきます。   ダメージ計算  ポケモンのダメージ計算は初代から現在までそこまで大きな変化はありません。最新世代ではダメージに関係する要素(アイテム等)が多く、それにより補正値の修正はあります...

    カテゴリ

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