0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

初めてのfetch(JSでの非同期通信・配列を送る)

Last updated at Posted at 2021-07-07

PHPファイルの文字コードが "Shift JIS" の環境で作成していました。

<?php
//〜PHPの処理色々省略〜
?>
 <!-- HTMLの記載色々省略 -->

<form method="post">
    <div id="main">
        <div id="search_item_box">
            <div id="search_item_num_0" data-num="0">
                商品カテゴリ選択:
                <!-- name="item_cate[]"とすることで配列入力を配列型にすることができる -->
                <label><input type="radio" name="item_cate[0]" value="none" checked>なし</label >
                <label><input type="radio" name="item_cate[0]" value="product">食材</label >
                <label><input type="radio" name="item_cate[0]" value="product_tokubai">特売(食材)</label >
                <label><input type="radio" name="item_cate[0]" value="product_b">食材以外</label >
                <label><input type="radio" name="item_cate[0]" value="product_b_tokubai">特売(食材以外)</label >
                <label><input type="radio" name="item_cate[0]" value="product_new">新登録商品(食材)</label >
                <label><input type="radio" name="item_cate[0]" value="product_b_new">新登録商品(食材以外)</label >
                <div>
                    品番シリアル:
                    <input type="text" name="dat_serial[0]" value="">
                    <button type="button" onclick="item_remove('search_item_num_0')"><i class="fas fa-times"></i></button>
                </div>
            </div>
        </div>

        <div>
            <button type="button" onclick="asynchronous_btn(this.form, 'search')">非同期検索</button>
            <!-- このボタンを押すと非同期通信が発生 -->

            <button type="button" onclick="item_addition()"><i class="fas fa-plus"></i></button>
            <!-- このボタンを押すと入力欄が増える -->
        </div>

        <div id="search_item_display">
            <!-- ここに検索結果が表示される -->
        </div>
    </div>

</form>




<script>

 // 商品検索欄追加
            let searchNum = 0;
            function item_addition(){
                searchNum++;

                let searchItem = `<div id="search_item_num_${searchNum}" data-num="${searchNum}">
                                    商品カテゴリ選択:
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="none" checked>なし</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product">食材</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_tokubai">特売(食材)</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_r">ロイヤルキッチン</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_b">食材以外</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_b_tokubai">特売(食材以外)</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_gift">ギフト食材</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_new">新登録商品(食材)</label >
                                    <label><input type="radio" name="item_cate[${searchNum}]" value="product_b_new">新登録商品(食材以外)</label >
                                    <div>
                                        品番シリアル:
                                        <input type="text" name="dat_serial[${searchNum}]" class="to_check" value="">
                                        <button type="button" onclick="item_remove('search_item_num_${searchNum}')"><i class="fas fa-times"></i></button>
                                    </div>

                                </div>`;

                const target = document.getElementById('search_item_box');

                target.insertAdjacentHTML('beforeend', searchItem);
            }


            // 商品検索欄削除
            function item_remove(searchItemNum){
                const removeTarget = document.getElementById(`${searchItemNum}`);
                removeTarget.remove();
            }



// 非同期検索
function asynchronous_btn(form) {
    let displayTarget = '';
    let item_cate_arr=[];
    let dat_serial_arr=[];

    let searchItems = document.getElementById('search_item_box');
    // search_item_boxのidの要素を取得
    let itemSearchCount = searchItems.childElementCount;
    // searchItemsの子要素の数を数える
    

    // formの配列をJSの配列に転換
    for (let i = 0; i < itemSearchCount; i++) {
        let searchItemDataset = searchItems.children[i].dataset.num;
        // searchItemsのi番目の子要素のデータ属性の値を取得

        item_cate_arr.push(form.elements[`item_cate[${searchItemDataset}]`].value)
        // formのname属性がitem_cate[]の値を一つずつ取り出し、JSの配列に入れる
      
        dat_serial_arr.push(form.elements[`dat_serial[${searchItemDataset}]`].value)
        // formのname属性がdat_serial[]の値を一つずつ取り出し、JSの配列に入れる
    }


    // 送信処理
    fetch('./asynchronous_search.php',{// 送信先
        method:'POST',// 送信メソッド
        body: new URLSearchParams({// 送信する値
            item_cate : JSON.stringify(item_cate_arr),
            dat_serial : JSON.stringify(dat_serial_arr),
            // JSON.stringify()でJSON形式にエンコードすることで、「文字列化」して送信できるようにする
        })
    })// ここでasynchronous_search.phpに送信される


    // asynchronous_search.phpから結果が返ってくる
    .then(response => response.json())//JSON形式できちんと返ってきているかの確認(値は.thenの引数に入る)

    .then(data => {//成功時の処理(値は.thenの引数に入る)
        displayTarget = document.getElementById('search_item_display');

        displayTarget.innerHTML = data;
        // displayTargetの子要素として返ってきた値を設置(HTML形式で返すようにしている)
    })

    .catch(error => {
        // ネットワークエラーでも !response.ok でもここで処理できる
        console.error('エラーが発生しました', error);
    });

}
</script>
asynchronous_search.php
<?php
//送信された値を受け取る
$p_item_cate_arr = '';
isset($_POST['item_cate']) && $p_item_cate_arr = json_decode($_POST['item_cate']);

$p_dat_serial_arr = '';
isset($_POST['dat_serial']) && $p_dat_serial_arr = json_decode($_POST['dat_serial']);

//////////////////////////////////////////////////////////////////////
// $search_result = DBから該当のデータを取得(省略)
//////////////////////////////////////////////////////////////////////


//商品検索結果表示
$search_result_disp = '';
if($search_result){
    if(empty($search_result)){
        $search_result_disp .= '<p><font color="red">対象商品が見つかりません。</font></p>';
    }else{
        $search_result_disp .= '<table border="1" style="border-collapse: collapse">
                                    <tr>
                                        <th>品番</th>
                                        <th>商品名</th>
                                        <th>単価</th>
                                    </tr>
                                ';
        foreach($search_result as $item_dat){
            $search_result_disp .= sprintf('<tr>
                                                <td>%1$s</td>
                                                <td>%2$s</td>
                                                <td>%3$s円</td>
                                            </tr>
                                            '
                                        ,$item_dat['dat_serial']
                                        ,$item_dat['dat_item']
                                        ,number_format($item_dat['unit_price'])
            );
        }
        $search_result_disp .= '</table>';
    }
}

mb_convert_variables("utf-8","sjis",$search_result_disp);
//文字コードをsjisからutf-8にエンコード
header('Content-Type: application/json; charset=utf-8');
//送り返すデータのタイプを宣言・文字コードも宣言
echo json_encode($search_result_disp);
//JSON型にエンコードして送り返す
//(PHPのjson_encodeでは文字コードがutf-8になるらしい。その為先にutf-8に変換しておかないとエラーになる)


exit;
// 処理を切る為

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?