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

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

ただいまの
回答率

88.82%

PHPとjQueryを使用した動的なセレクトボックスの実現

解決済

回答 1

投稿 編集

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

kans00229

score 28

PHPバージョン5.6 
フレームワーク等は使用しておりません。

下記のフォームで、実現したい動きが
ございます。

現在の動作はコチラです。
・https://paiza.io/projects/5PgxAfnUWt17lyc4NpfGyw

■実現したい動作
①フォームの「交代時間」部分について、フォーム操作の「追加」でフォームを
増加した時に、増加する前の選択していた時間(1~120)より後の数字のみ
選択可能にしたい。
例:一番目のフォームが30なら、二番目は31~120までしか選べない

②フォームの「交代選手名」部分について、フォーム操作の「追加」でフォームを
増加した時に、増加する前に「交代選手名」選択された選手名を除外して表示。
また、フォームを増加する前に「IN選手名」で選択された選手名を選択できるようにさせたい。

③フォームの「IN選手名」部分について、フォーム操作の「追加」でフォームを
増加した時に、増加する前と現在の「交代選手名」で選択されて選手名とおよび
フォームを増加する前の「IN選手名」で選択された選手名を除外して表示させたい。

説明が解りずらいかと思われますが、フォーム操作で「追加」を押した際とセレクトボックス
の選択によって、セレクトボックスが状況に応じて選択項目が変化するという動きを実現
したいと考えています。

私の知識では実現が難しく、本サイトでご教授して頂き解決した物も多い
ため、皆様のお力をお貸し頂ければと思います。

宜しくお願い致します。

<?php
// Here your code !
$in_member = array(
  '0' => array(
      'id_mbr' => '1', 
      'name_mbr' => '田中', 
  ),
  '1' => array(
      'id_mbr' => '2', 
      'name_mbr' => '鈴木', 
  ),
  '2' => array(
      'id_mbr' => '3', 
      'name_mbr' => '山田', 
  ),
  '3' => array(
      'id_mbr' => '4', 
      'name_mbr' => '中山', 
  ),
  '4' => array(
      'id_mbr' => '5', 
      'name_mbr' => '本田', 
  ),
  '5' => array(
      'id_mbr' => '6', 
      'name_mbr' => '香川', 
  )  
);
$out_member = array(
  '0' => array(
      'id_mbr' => '1', 
      'name_mbr' => '田中', 
  ),
  '1' => array(
      'id_mbr' => '2', 
      'name_mbr' => '鈴木', 
  ),
  '2' => array(
      'id_mbr' => '3', 
      'name_mbr' => '山田', 
  ),
  '3' => array(
      'id_mbr' => '4', 
      'name_mbr' => '中山', 
  ),
  '4' => array(
      'id_mbr' => '5', 
      'name_mbr' => '本田', 
  ),
  '5' => array(
      'id_mbr' => '6', 
      'name_mbr' => '香川', 
  )  
);

//スコア部分
$cnt_mem = isset($game_info["cnt_mem"]) ? $game_info["cnt_mem"]: 1;
$change_time = isset($game_info["change_time"]) ? $game_info["change_time"]: 0;
$in_mbr = isset($game_info["in_mbr"]) ? $game_info["in_mbr"]: 0;
$out_mbr = isset($game_info["out_mbr"]) ? $game_info["out_mbr"]: 0;
?>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script>
        $(function() {
//選手交代部分

            $('.mem_clear').on('click', '.mem_clear_btn', function(){
                $('.mem_box:first').find('option.outmem').attr('selected', false);              
                $('.mem_box:first').find('option.outintime').attr('selected', false);                  
                $('.mem_box:first').find('option.inmem').attr('selected', false);   
            });              
            $(".btn_delete_btn_mem:not(:first)").show();
                var cloneElem4 = $('.mem_box:last');

            $('.memadd').on('click', '.memadd_btn', function(){
                $('.mem_box:last').after(cloneElem4.clone(true));
                $('.mem_box:last').find('option.outmem').attr('selected', false);                
                $('.mem_box:last').find('option.outintime').attr('selected', false);                   
                $('.mem_box:last').find('option.inmem').attr('selected', false);                  
                $(".cnt_mem").val(1+Number($(".cnt_mem").val()));
                $(".btn_delete_btn_mem:not(:first)").show();
                $(".mem_clear:not(:first)").hide();                               
                $(".for_dele_mem:not(:first)").show();                

            });

                $('.for_dele_mem').on('click', '.btn_delete_btn_mem', function(){
                $(this).closest(".mem_box").remove();
                $(".cnt_mem").val(Number($(".cnt_mem").val()-1));
            });       
         }); 
</script>
<!--選手交代-->                        
<div class="panel panel-default dispon">
    <div class="thumbnail_title thumbnail_title_freeimg"><i class="fa fa-user" aria-hidden="true"></i>選手交代
        <span style="text-align:right !important;display:inline-block;float: right;margin-right: 10px;font-size:17px;"><i class="fa fa-info-circle" aria-hidden="true"></i></span> 
    </div>       
    <div class="panel-body">
                                      <?php for ($i = 0; $i < $cnt_mem; $i++) { ?> 
                           <div class="mem_box">
                                  <div class="col-md-2 col-sm-12 col-xs-12 form_nonepd">
                                      <label class="control-label" for="com_score">交代時間</label>
                                      <select class="form-control ubstitution_one" name="change_time[]">
                                          <option value="0">交代時間</option>
                                            <?php for ($gtime = 1; $gtime < 121; $gtime++) { ?>        
                                                    <option class="outintime" <?php if(!isset($_POST['result_add_btn'])) { if($change_time[$i] == $gtime) { echo 'selected="selected"';}} ?>><?php echo $gtime; ?></option>
                                            <?php } ?>  
                                      </select>
                                  </div>                               
                                  <div class="col-md-2 col-sm-12 col-xs-12 form_nonepd">
                                      <label class="control-label" for="com_score">交代選手名</label>                                      
                                      <select class="form-control out_mbr_one" name="out_mbr[]">
                                          <option value="0">交代選手名</option>
                                              <?php foreach ($in_member as $key => $in_mem) { ?>                                           
                                                  <option class="outmem" id="out_mbr_one<?php echo $in_mem['id_mbr']; ?>" value="<?php echo $in_mem['id_mbr']; ?>" <?php if(!isset($_POST['result_add_btn'])) {  if($out_mbr[$i] == $in_mem['id_mbr']) { echo 'selected="selected"';} }?>><?php echo $in_mem['name_mbr']; ?></option>                                     
                                              <?php } ?>  
                                      </select>
                                  </div>
                                  <div class="col-md-2 col-sm-12 col-xs-12 form_nonepd">
                                      <label class="control-label" for="com_score">IN選手名</label>                                      
                                      <select class="form-control in_mbr_one" name="in_mbr[]">
                                          <option value="0">IN選手名</option>
                                              <?php foreach ($out_member as $key => $out_mem) { ?>                                           
                                                   <option class="inmem" id="in_mbr_one<?php echo $out_mem['id_mbr']; ?>" value="<?php echo $out_mem['id_mbr']; ?>" <?php if(!isset($_POST['result_add_btn'])) {  if($in_mbr[$i] == $out_mem['id_mbr']) { echo 'selected="selected"';}} ?>><?php echo $out_mem['name_mbr']; ?></option>                                     
                                              <?php } ?>  
                                      </select>
                                  </div>
                                        <div class="col-sm-2 col-xs-12 form_nonepd mem_clear">
                                            <label class="control-label">フォーム操作</label> 
                                            <button type="button" class="btn btn-warning btn-block mem_clear_btn" name="clear_btn" style="padding-left:25px;padding-right:25px;"><i class="fa fa-times" aria-hidden="true"></i>クリア</button>
                                        </div>
                                            <div class="col-sm-2 col-xs-12 for_dele_mem form_nonepd" style="display:none;">
                                                <label class="control-label" for="btn_delete_btn_mem">フォーム操作</label>
                                                <button type="button" class="btn btn_delete_btn_mem btn-block" style="padding-left:25px;padding-right:25px;" name="btn_delete_btn_mem"><i class="fa fa-trash-o" aria-hidden="true"></i>削除</button> 
                                            </div>                                
                                            <div class="col-sm-2 col-xs-12 form_nonepd memadd">
                                                      <label class="control-label" for="memadd_btn">フォーム操作</label>
                                                <button type="button" class="btn btn-info btn-block memadd_btn" name="memadd_btn" style="padding-left:25px;padding-right:25px;"><i class="fa fa-plus" aria-hidden="true"></i>追加</button>
                                                <input type="hidden" name="cnt_mem" id="cnt_mem" class="cnt_mem" value="<?php echo $cnt_mem; ?>">
                                            </div>


                                 </div>
                                 <?php } ?> 
                                 </div>     
                                 </div>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • karamarimo

    2017/10/16 13:01

    フォームを追加した後に、前の行の値を変更した場合どうなって欲しいのでしょうか?

    キャンセル

  • kans00229

    2017/10/16 14:00

    karamarimo様 ご返答ありがとうございます。フォームをを追加した後で、前の行を変更した場合も、同じように連動出来れば最も良いです。

    キャンセル

回答 1

checkベストアンサー

+1

ちょっと仕様がわかりづらいのですが
outで選んだ選手をinに表示したくないのでしょうか?
そもそもoutする選手はプレー中で、inする選手はベンチにいるわけですから
データの属性が最初から違うのでは?
データ構造を変えないとどちらにしてもロジックがおかしいことになると思います。

また1行目のクリアの位置が2行目には削除というのはあまりよくありません。
1行目がクリアなら2行目にもクリアを置き別途削除を置きます
そうでないなら1行目のクリアは辞めたほうがいいでしょう。

全体の流れとしては
基本的には1行目をcloneしてつかい、交代時間は1行目の値をベースに
いらないデータを削除するかdisabledにするかでしょうか
場合によってはajaxでデータをおくって初期値を調整する方法もありますが
そこまでするほどではないかと。

 sample

以下ちょっとバグバグしてますが、ざっとした流れはこれでわかると思います。
focus時に削除処理をいれています

$(function() {
  var out_mbr=["先発01","先発02","先発03","先発04","先発05","先発06","先発07","先発08","先発09","先発10","先発11"];
  var in_mbr=["控え01","控え02","控え03","控え04","控え05","控え06"];
  $(document).on('focus','select[name="change_time[]"]',function(){
    var me=$(this);
    me.find('option:gt(0)').remove();
    for(var i=0;i<=120;i++){
      me.append($('<option>').val(i).text(i));
    };
    var v=parseInt(me.closest('.row').prev('.row').find('select[name="change_time[]"]').val());
    me.find('option').filter(function(){return $(this).val()!="" && parseInt($(this).val())<v;}).remove();

  });
  $(document).on('focus','select[name="out_mbr[]"]',function(){
    var me=$(this);
    me.find('option:gt(0)').remove();
    out_mbr.forEach(function(i){ me.append($('<option>').val(i).text(i));});
    $('select[name="out_mbr[]"]').filter(function(){return $(this).val()!=="";}).each(function(){
      var v=$(this).val();
      me.find('option').filter(function(){return $(this).val()==v;}).remove();
    });
  });
  $(document).on('focus','select[name="in_mbr[]"]',function(){
    var me=$(this);
    me.find('option:gt(0)').remove();
    in_mbr.forEach(function(i){ me.append($('<option>').val(i).text(i));});
    $('select[name="in_mbr[]"]').filter(function(){return $(this).val()!=="";}).each(function(){
      var v=$(this).val();
      me.find('option').filter(function(){return $(this).val()==v;}).remove();
    });
  });
  $(document).on('click','[type=button][value=追加]',function(){
    var r1=$(this).closest('.row');
    var r2=r1.clone();
    r2.find('[type=button][value=削除]').css('visibility','visible').prop('disabled',false);
    r1.after(r2);
  });
  $(document).on('click','[type=button][value=削除]',function(){
    $(this).closest('.row').remove();
  });
});
<div class="row">
<select name="change_time[]">
<option value="">交代時間</option>
</select>
交代選手名
<select name="out_mbr[]">
<option value="">OUT選手</option>
</select>
<select name="in_mbr[]">
<option value="">IN選手名</option>
</select>
<input type="button" value="削除" style="visibility:hidden" disabled>
<input type="button" value="追加">
</div>

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/10/16 14:07

    yambejp様
    ご返答有難うございます。

    ボタンの構造につきましては、確かに間違いを招きやすいと
    思いますので、表示の変更を検討致します。

    outとinの選手のデータ構成に関しまして、確かにそうですね。
    分けたいと思います。

    有難うございます。

    キャンセル

  • 2017/10/16 18:21

    sampleつけておきました、参考になればと

    キャンセル

  • 2017/10/17 09:24

    yambejp様
    ご回答有難うございます。

    sampleまでつけて頂き、誠に感謝致します。

    本当に有難うございます。

    キャンセル

  • 2017/11/21 12:26

    yamabejp様 先日はご回答頂きまして誠に有難うございました。

    ■先発メンバーを選ぶセレクトボックス(全体メンバーから最大11名選択)
    ■交代メンバーを選ぶセレクトボックス(先発メンバーを選ぶセレクトボックスで選択したもの)
    ■控えメンバーを選ぶセレクトボックス(全体のメンバーから先発メンバー除いたもの)

    先日、お教え頂きましたサンプルの「out_mbr」「in_mbr」の値を
    先発メンバーを選ぶセレクトボックスを同一ページ内に設置して、選んだ選手(最大11名)
    をout_mbrの配列に入れる。

    in_mbrには、全体のメンバーからout_mbrを引いた値で配列を作成するという動的な動きが
    可能でしょうか?

    ご教授頂ければ幸いでございます。
    宜しくお願い致します。

    キャンセル

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

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

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