• 投稿日:2022年02月26日 15時58分52秒
  • 更新日:2022年03月03日 09時32分10秒
親要素を指定してそれ以下にある入力項目値を連想配列で取得する

親要素を指定してそれ以下にある入力項目値を連想配列で取得する

デモ

Get_inputDocumentValue( targetSelecter )

get_inputDocumentValue( targetSelecter ){

    var resAry = {};

    // target以下の値を取得
    let elm_inputAry = document.querySelectorAll(targetSelecter + ' input, ' + targetSelecter + ' select, ' + targetSelecter + ' textarea');
    elm_inputAry.forEach(elm_input => {

        var elm_name = "";
        if(elm_input.name != '' && elm_input.name !== null){
            elm_name = elm_input.name;
        }else if(elm_input.id != '' && elm_input.id !== null){
            elm_name = elm_input.id;
        }else {
            return; // idとname属性が未設定の場合は飛ばす
        }

        // type別で特別な処理をする場合の対応
        var elm_val = "";
        // console.log(elm_input);
        switch(elm_input.type){
            case "radio":
                
                if(resAry[elm_input.id]  == false){
                    resAry[elm_input.id] = ""; // 空でも項目を作成するための処理
                }

                /* checkedを確認したもののみを処理する */
                if(elm_input.checked){
                    elm_val = elm_input.value;
                    break;
                }else{
                    return; // 未選択なものは飛ばす
                }
                break;

            case "checkbox":
                /* checkedを確認したもののみを処理する */
                if(elm_input.checked){
                    elm_val = 1; 
                }else{
                    elm_val = 0;
                }
                break;

            default:
                
                elm_val = elm_input.value;
        }

        resAry[elm_name] = elm_val; // 配列に追加

    });

    return resAry;
}

説明

引数で指定したid値を持つ要素を親として、子要素のinputとselectの値を取得します。取得した値はname属性またはid属性の値をキーとして連想配列で返します。

この関数のメインは指定要素以下の要素を取得する以下の行です。これで指定要素以下の<input>と<select>要素を取得しています。

  • 6:let elm_inputAry = document.querySelectorAll(targetSelecter + ‘ input, ‘ + targetSelecter + ‘ select, ‘ + targetSelecter + ‘ textarea’);

そしてこの関数の肝は上記2行のすぐしたにあるこの処理です。

    let elm_inputAry = document.querySelectorAll(targetSelecter + ' input, ' + targetSelecter + ' select, ' + targetSelecter + ' textarea');
    elm_inputAry.forEach(elm_input => {

        var elm_name = "";
        if(elm_input.name != '' && elm_input.name !== null){
            elm_name = elm_input.name;
        }else if(elm_input.id != '' && elm_input.id !== null){
            elm_name = elm_input.id;
        }else {
            return; // idとname属性が未設定の場合は飛ばす
        }

これは「連想配列のキーはname属性があればそれを、なければid属性を、それもなければ処理を抜ける」という分岐処理です。

なぜこんなことをしているのか。

一つは「type=radio」なinput要素の値です。id毎に「選択されているか」を取得するのではなく項目毎に「今選択されているものの値」を取得したかったからです。

もう一つがid属性はWEBページ内で一意なものであり、そのため同じ項目名のデータが複数存在する場合純粋な項目名がid属性値に設定されない場合があるためです。

例えば、同じ構造のデータを比較する場合などです。比較なので同じ項目名のデータが複数存在することになります。そうなるとid属性値は後ろに「-bef」「-aft」などをつけて区別することになります。ということは上記関数がid属性値をキーにした場合これが付いた値(例:company-name-bef)がキーとなってしまいます。

そうなると取得した値を使って何かしようとした場合、「取得した項目名 + -bef or -aft」ってことを明記してあげる必要が出ます。そのため比較前/後で同じ処理をしたいのに同じ処理を前後毎に作成する、または配列などに入れ直すということをしなくてはならないため、とても面倒です。

そこでname属性があればそれを優先することで、項目名(例:company-name)をキーにすることが出来ます。

もちろんこうすることで「指定要素以下に同じname属性の要素が複数ある」場合に問題が発生します。でもほとんどの原因はname属性の命名規則または取得する親要素の指定方法が問題のはずです。解決方法として全部まとめて取得するのではなく、例えば比較前と比較後を分けて取得するなどしてください。

詳細

最後に

画面の内容を取得するとき、項目が多かったりIDと覚えてないとかって問題がありますよね(あるよね?)。

この関数を使えば入力項目をまとめて取ってくるのでかなり楽ができます。私がよくやるのはname属性と取得・更新するテーブルのフィールド名を揃えることです。こうすることでajaxを使いphpで作成したテーブル別更新処理にそのまま渡すことが出来ています。

最後に

WEB AR開発 A-Frame AR.js
JSアニメーション:文字の登場
画面右下固定のスクロールボタン
ajax通信でWordPressの記事情報を取得する
要素を取得・操作する
Tabulatorについて
モーダルな画面を表示をする
ある要素が画面に表示されたら処理を実行する