質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

コードを書いていて、よくわからなくなってしまいました SELECTBOXの作成とonChange

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,030

Z-TALBO

score 493

はじめに

今回、とりあえず質問を書きましたが、やはりいろいろ細かな部分でわかりづらさが目立ちましたのと、ご指摘いただいた内容として、一度質問を書き直しております。
当然、質問の書き直しはNGかと思いましたが、基本的な内容は特に変更は無く、もう少しわかりやすく書き直すことが目的であることをはじめにご容赦ください。

1.まずはHTMLでのコードで基本の表示をご覧ください

<form action="" method="POST">
        <?php for($i = 0; $i < 3; $i++) { ?>
        <select name="test[<?= $i; ?>][staff]">
            <?php
                $staffs = select_staff_db();
                foreach($staffs as $staff) {
                    $staff_id   = $staff['staff_id'];
                    $staff_name = $staff['staff_name'];
                    echo "
                    <option value=".$staff_id.">".$staff_name."</option>";
                }
            ?>
        </select>
        <select name="test[<?= $i; ?>][dakoku]">
            <?php
                $dakokus = select_dakoku_db();
                foreach($dakokus as $dakoku) {
                    $dakoku_id   = $dakoku['dakoku_id'];
                    $dakoku_name = $dakoku['dakoku_name'];
                    echo "
                    <option value=".$dakoku_id.">".$dakoku_name."</option>";
                }
            ?>
        </select><br />
        <?php } ?>
        <input type="submit" name="submit" value="送信">
    </form>


staffとdakokuを選択して、送信を押すという動作になります。
A - 1
B - 2
A - 3
というように、名前は重複してもOKだし、選択していなくてもOKです。
※現在はこれで動作しており、PHPで選択されてなかったら等条件で処理を分けるようにしております。

2.やりたいこと

1のやり方で一応な動作はできておりますが、今回やりたいことは、、、
staffのSelectBoxを選択する
※ここではAを選択したとします。

自動的にというか、Aの値を元にDBにアクセスします。

DBに値が無かった場合
dakokuのSelectBoxは特にいじらずそのまま出力。

DBに値があった場合
※ここはもう少し条件による振分はありますが、、、
dakokuのSelectBoxの値においてDBの値と一致した値はdisabledになり、選択できないようにする。

これが、今回やりたいことになります。

3.とりあえず自分でやってみたこと

<!-- staff側のSelectBoxにonChangeをつけてみた -->
<form action="" method="POST">
        <?php for($i = 0; $i < 3; $i++) { ?>
        <select name="test[<?= $i; ?>][staff]" onChange="this.form.submit()">
            <?php
                $staffs = select_staff_db();
                foreach($staffs as $staff) {
                    $staff_id   = $staff['staff_id'];
                    $staff_name = $staff['staff_name'];
                    echo "
                    <option value=".$staff_id.">".$staff_name."</option>";
                }
            ?>
        </select>
        <select name="test[<?= $i; ?>][dakoku]">
            <?php
                $dakokus = select_dakoku_db();
                foreach($dakokus as $dakoku) {
                    $dakoku_id   = $dakoku['dakoku_id'];
                    $dakoku_name = $dakoku['dakoku_name'];
                    echo "
                    <option value=".$dakoku_id.">".$dakoku_name."</option>";
                }
            ?>
        </select><br />
        <?php } ?>
        <!-- <input type="submit" name="submit" value="送信"> -->
    </form>


この場合だと、<input type="submit">のせい?でonChangeが動かない様だったので、無しにしました。
これで、とりあえずSelectBoxを変更するとPOSTされるようになりました。

4.PHPで条件などを考えてみた

さて、上記まで、とりあえずsubmitされるようにはなりました。
次に、上記までの場合3行あっても無駄になる状況なのがわかります。
ですので、選択した値に関してはそのまま表示されるようにしたいという思いが出てきますので、次から、PHPにてその辺りを一気に書いてみました。

<?php
            $test = filter_input(INPUT_POST, 'test', FILTER_DEFAULT, array('flags' => FILTER_REQUIRE_ARRAY));
            $staffs = select_staff_db();
            $dakokus = select_dakoku_db();
            if(is_null($test)) {
                for($i = 0; $i < 3; $i++) {
                    echo "
                    <select name='test[{$i}][staff]' onChange='this.form.submit()'>";
                    foreach($staffs as $staff) {
                        $staff_id = $staff['staff_id'];
                        $staff_name = $staff['staff_name'];
                        echo "
                        <option value=".$staff_id.">".$staff_name."</option>";
                    }
                    echo "
                    </select>
                    <select name='test[{$i}][dakoku]'>";
                    foreach($dakokus as $dakoku) {
                        $dakoku_id = $dakoku['dakoku_id'];
                        $dakoku_name = $dakoku['dakoku_name'];
                        echo "
                        <option value=".$dakoku_id.">".$dakoku_name."</option>";
                    }
                    echo "
                    </select>";
                }
            } else {
                for($i = 0; $i < 3; $i++) {
                    $post_staff = $test[$i]['staff'];
                    echo "
                    <select name='test[{$i}][staff]' onChange='this.form.submit()'>";
                    foreach($staffs as $staff) {
                        $staff_id = $staff['staff_id'];
                        $staff_name = $staff['staff_name'];
                        if($staff_id == $post_staff) {
                            echo "<option value=".$staff_id." selected>".$staff_name."</option>";
                        } else {
                            echo "<option value=".$staff_id.">".$staff_name."</option>";
                        }
                    }
                    echo "
                    </select>";
                    echo "
                    <select name='test[{$i}][dakoku]'>";
                    $dakoku_date = date('Y-m-d');
                    $dakoku_check = dakoku_check_db($dakoku_date, $post_staff);
                    if(empty($dakoku_check)) {
                        foreach($dakokus as $dakoku) {
                            $dakoku_id = $dakoku['dakoku_id'];
                            $dakoku_name = $dakoku['dakoku_name'];
                            echo "<option value=".$dakoku_id.">".$dakoku_name."</option>";
                        }
                    } else {
                        foreach($dakoku_check as $check) {
                            $check_id = $check['dakoku_id'];
                            foreach($dakokus as $dakoku) {
                                $dakoku_id = $dakoku['dakoku_id'];
                                $dakoku_name = $dakoku['dakoku_name'];
                                if($check_id == $dakoku_id) {
                                    echo "<option value=".$dakoku_id." disabled>".$dakoku_name."</option>";
                                } else {
                                    echo "<option value=".$dakoku_id.">".$dakoku_name."</option>";
                                }
                            }
                        }
                    }
                    echo "
                    </select>";
                }
            }
        ?>


とりあえず、POSTが無い(最初にアクセスした時)は全て選択されていない状態で、SelectBoxがある状況にしつつ、選択されると、その名前は保持されたままにできるようになりました。

さらに、dakoku_checkを行い、データがあるか無いかを判定して、無ければ通常のSelectを表示させ、データがある場合にはそのデータの部分だけdisabledになるという最終的にやりたい部分を考えてみたのですが、、、、

5.最後にできていない部分

確かに、disabledにはなりました!
が、、、、データがある分だけ回してしまっていると思うので、どうもうまく行っておりません。
症状としては、、、
dakokuが下記のようにあるとして、データがAだけだった場合
A disabled
B
C
D
E
のようになりました。
dakokuが下記のようにあるとして、データがAとBだった場合
A disabled
B
C
D
E

A
B disabled
C
D
E
のようになりました。
これはdakoku_checkをforeachで回しちゃってるからそりゃ回ってるんだろうとは思うのですが、、、この辺りの動かせ方がどうもぴんと来ていないのが実際です。。

できて欲しい形は
dakokuが下記のようにあるとして、データがAとBだった場合
A disabled
B disabled
C
D
E
です。

6.DBやfunctionあたりの情報

最後になってしまい申し訳ありません。
DBのTableとしては、今回3つ使用します。
[staff]
staff_id,
staff_name

[dakoku]
dakoku_id,
dakoku_name

[dakoku_date]
table_id,
staff_id,
dakoku_id,
dakoku_time

function select_staff_db() {
    $dbh = connectDb();
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $sql = "SELECT staff_id, staff_name FROM staff";
    $stmt = $dbh->prepare($sql);
    $stmt->execute();
    $staffs = $stmt->fetchAll();
    return $staffs;
}

function select_dakoku_db() {
    $dbh = connectDb();
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $sql = "SELECT dakoku_id, dakoku_name FROM dakoku";
    $stmt = $dbh->prepare($sql);
    $stmt->execute();
    $dakokus = $stmt->fetchAll();
    return $dakokus;
}

function dakoku_check_db($dakoku_date, $post_staff) {
    $dbh = connectDb();
    $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    $sql = "SELECT dakoku_id FROM dakoku_date WHERE staff_id = :post_staff AND CAST(dakoku_time as DATE) = :dakoku_date";
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(':post_staff', $post_staff, PDO::PARAM_INT);
    $stmt->bindValue(':dakoku_date', $dakoku_date, PDO::PARAM_STR);
    $stmt->execute();
    $dakoku_check = $stmt->fetchAll();
    return $dakoku_check;
}

7.最後に

今回は、SelectBoxの部分についてだけを質問しておりますが、最終的にはそうやって選択したデータを送信して、登録するという作業があることはあります。。。
その部分については、またこの質問が解決しましたら質問させていただこうと思っております。

分かりづらい質問になってしまい大変申し訳ございませn。。。
ご指摘、不足した情報等ありましたら、お知らせくださればと思います。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

今回は、解決を見送ります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

select_staff_db()の仕様が抜けていてちょっとわかりづらいです

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/10/27 09:32

    一応、現在のfunctionの部分とDBの部分を追記してみました。

    キャンセル

  • 2016/10/27 11:03

    全体のフォーマットがわからないのですが、
    スタッフ選択セレクトボックスが3つある?
    打刻選択セレクトボックスが3つある?
    それぞれの相関関係がわかりません
    一度HTMLベースでベタに書き出して挙動の説明をして頂いたほうがよいかもしれません。

    キャンセル

  • 2016/10/27 17:15

    遅くなりましたが、質問内容を改めて書かせていただきました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る