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

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

ただいまの
回答率

88.19%

動的にoptionが変わるセレクトボックスを作成し、POST送信された後も選択された値を保持したい

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 398

AkihiroIshii

score 64

やりたいこと

動的にoptionの内容が変化するセレクトボックスを用意し、POST送信されても選択された値を保持したいです。開発環境はFuelPHP(1.8.2)です。

試したこと

次の動画で具体例を示します。選択した「種類」によって「食品」に表示する項目が動的に変化するようにしています。
イメージ説明
確認ボタンでPOST送信したあと、PHPで項目を設定した「種類」フィールドの値は保持できました。一方、javaScriptで項目を設定した「食品」フィールドは値が保持できません(バナナを保持したいのに、にんじんに初期化されてしまいます)。

現在の方針と懸念事項

「種類」フィールドの内容は固定するためPHP処理で内容を設定しています。一方、「食品」フィールドは「種類」が変更されたことを検知して内容を変えたいため、javaScriptで制御しようと考えました。

しかし、「食品」の値をjavaScriptで定義し、POST送信された時にフォームをrepopulate()するという流れでは、「食品」の値を保持するのが難しいのかもしれないと感じています。

質問(相談)

POST送信された後も選択された値を保持するためには、どのように実装すれば良いでしょうか?

具体的な方法ではなくとも、大まかな流れについてのご意見や、上述の方針に対するご指摘をいただけると助かります。

コード

コントローラ

<?php

class Controller_Home extends Controller
{
  public function action_index()
  {
    // 条件入力フォームを作成
    $form = Fieldset::forge('sample');

    // 種類を選択するセレクトボックス
    $opts = array('1' => '1:野菜', '2' => '2:果物');
    $form->add('type', '種類', array('type' => 'select'))
      ->set_options($opts);

    // 種類によって内容が変わるセレクトボックス
    $form->add('food', '食品', array('type' => 'select'));

    $form->add('submit', '', array('type' => 'submit', 'value' => '確認'));

    if (Input::method() === 'POST')
    {
      $form->repopulate();
    }

    // ビューを生成
    $view = View::forge('home');
    $view->set_global('form', $form->build(''), false);
    return $view;
  }
}

ビュー

<?php echo $form; ?>

<?php echo Asset::js('jquery.min.js'); ?>
<?php echo Asset::js('main.js'); ?>

javaScript

$(function(){
  // 初期処理
  if($('#form_food').val() === null){
    set_options('1'); // 空の場合は野菜のoptionを設定
  }

  // 種類フィールドが変更された時の処理
  $('#form_type').change(function(){
    var type = $(this).val(); // 1:野菜、2:果物

    // 食品フィールド(セレクトボックス)のoptionをクリア
    $('#form_food').children().remove();

    // 選択された種類によって、食品フィールドのoptionを設定
    set_options(type);
  });
});

function set_options(type)
{
  if(type === '1'){ // 野菜が選択された場合
    $('#form_food').append($('<option>').val('1').text('1:にんじん'));
    $('#form_food').append($('<option>').val('2').text('2:玉ねぎ'));
    $('#form_food').append($('<option>').val('3').text('3:じゃがいも'));
  }else{            // 果物が選択された場合
    $('#form_food').append($('<option>').val('4').text('4:りんご'));
    $('#form_food').append($('<option>').val('5').text('5:バナナ'));
    $('#form_food').append($('<option>').val('6').text('6:オレンジ'));
  }  
}

質問

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

hiddenか何かで引き継いで、
$('#form_type').change(function(){・・・・}).trigger('change');
した上で、hiddenの値で#form_foodのvalueを変えてください

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/12/21 11:33

    今回はhidden以外の方法を使いましたが、何かで引き継いでからvalueを変えるという方針をご提示いただいたことで解決に至りました。ありがとうございます。

    キャンセル

check解決した方法

0

主な流れを次のようにしました。

  1. POST送信された値を、コントローラからビュー経由でjavaScriptに渡す。
  2. javaScriptでフィールドの項目を生成してから、渡された値を設定する。

具体的には、下記のように修正したところ上手く動きました(差分を+-で示します)。

コントローラ

+    // javaScriptで再設定するためにビューに渡す変数
+    $food = (Input::post('food')) ? Input::post('food') : '1';

    // ビューを生成
    $view = View::forge('home');
    $view->set_global('form', $form->build(''), false);
 +   $view->set_global('food', $food);
    return $view;

ビュー

<?php echo $form; ?>

<?php echo Asset::js('jquery.min.js'); ?>
-<?php echo Asset::js('main.js'); ?>
+<?php echo Asset::js('main.js', array('id'=>'script_id','food'=>$food)); ?>

javaScript

$(function(){
  // 初期処理
-  if($('#form_food').val() === null){
-    set_options('1'); // 空の場合は野菜のoptionを設定
-  }
+  init();

  // 種類フィールドが変更された時の処理
/* 〜中略〜 */
});

+function init()
+{
+  // 選択された値を取得
+  var food = $('#script_id').attr('food');
+  var type = $('#form_type').val();
+
+  // 選択された値に基づきセレクトボックスの値を設定
+  set_options(type);
+  $('#form_food').val(food);  
+}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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