【Railsでアプリ開発中】プログラミング初心者の勉強ブログ #36
こんにちは。
36日目。セレクトボックスの使い方についてです。<select>、<option>タグの書き方から、JavaScriptでvalue値を取得し、値をajaxでコントローラーに渡す方法までを実装していきます。
はじめに
この記事は、railsフレームワークでオリジナルwebアプリ「免許学科試験学習サイト」作成中の僕が、プログラミングをしている中で気づいたことや学んだことを書いております。プログラミング初心者なので知識は少ないですが、現在通っているプログラミングスクール「DIVE INTO CODE」で学んでいることや、ネットで見つけた様々な記事を参考に記事を作成しております。
目次
[toc]
前回までの内容
前回の記事(【JavaScript】値に応じて表示させるプログレスバーを簡単に実装する)では、免許試験アプリの「マイページ画面」で、学習進捗のパーセンテージを表示するためプログレスバーを実装しました。ログインしたユーザーが解いた問題の正解・不正解をDBに保存し、マイページに進捗を表示させる流れです。
今回は「一問一答」機能を拡張し、問題数や出題範囲を選択して一問一答できる仕様にするため、「セレクトボックス」を用いてJavaScriptで値の取得までできるようにしました。
セレクトボックスの使い方
はじめに、セレクトボックスが何なのか書きます。
というのも、正直セレクトボックスなんて言葉を今回初めて知ったからです。
モーダルウィンドウにしろプログレスバーにしろアコーディオンにしろ、最近になるまで全く知りませんでした。
なので「セレクトボックス」がどんなものか、をまず書きます。
セレクトボックスとは
セレクトボックス とは、
こういうやつです。
「セレクトボックス」をクリックすると、「プルダウンリスト」が現れます。
最初見たとき、BootstrapとかjQueryのライブラリの類だと思ってたんですけど、そういうわけではなかったです。
HTMLの<select>タグだけで、ブラウザに表示できます。
<form>とか<button>とかと同じ感覚です。
セレクトボックスとプルダウンの基本コード
次、基本のコードになります。
<h4>問題数を選ぶ</h4> <select id="select_num"> <option value="5">5</option> <option value="10">10</option> <option value="15">15</option> <option value="20">20</option> <option value="30">30</option> </select>
<select>タグ・・・セレクトボックス
<option>タグ・・・プルダウンリスト
です。
これだけで
ブラウザで表示されます。
想像の10倍簡単でした。
セレクトボックスがHTMLのタグだけでできるんだったら、もっとHTMLのタグいろいろあってもいいんじゃないか、って思ってしまうくらい。
JavaScriptでセレクトボックスのvalue値を取得
先ほどの基本コードでボックスを表示したら、次はユーザーが選択したメニューをコンピュータ内部に伝えないといけません。
もう一度先ほどの基本コードを見ます。
<h4>問題数を選ぶ</h4> <select id="select_num"> <option value="5">5</option> <option value="10">10</option> <option value="15">15</option> <option value="20">20</option> <option value="30">30</option> </select>
<option>タグに「value=” “」がついてます。
このvalueに入れた値が「取得される要素」となります。
この値をJavaScriptで取得します。
<script>タグ内で、
var select_num = $('#select_num').val();
<select>タグに当てたidをセレクタにし「.val( );」メソッドを行うと、
<option>タグに当てたvalue値を引っ張ってこれます。
実際に書いたJSのコード。
$(function(){ $('.kettei_btn').click(function(){ #「決定ボタン」クリック時のアクション定義 $(this).hide(); #「決定ボタン」を隠す $('.select_num_div').hide(); $('.select_field_div').hide(); $('.select_questions_div').hide(); #セレクトボックスを3つとも隠す $('.start_btn').fadeIn(); #「はじめる」ボタンをフェードイン var select_num = $('#select_num').val(); var select_field = $('#select_field').val(); var select_questions = $('#select_questions').val(); #セレクトボックスのvalue値を変数にそれぞれ格納 $.ajax({ url: '/itimon_ittous/index', type: 'GET', dataType: 'html', async: true,cd data: { select_num: select_num, select_field: select_field, select_questions: select_questions }, }); #ajaxでitimon_ittousコントローラに飛ばし、indexアクションを叩く。 #value値を格納した変数をパラメータで飛ばす。 }); });
※ajaxについては、(【Rails】AjaxでJavaScriptの変数をコントローラーに渡す【DIVE INTO CODE】)で実装の流れを載せてます。
全部選択して決定を押すと、セレクトボックスと「決定」ボタンが消え、
「はじめる」ボタンが現れます。
ターミナルを確認すると、
パラメータがちゃんと送られてきてます。
これでvalue値をコントローラで使うことができます。
今回の場合だったら、@num = params[:select_num]で、
@numに文字列の”10″が取得可能です。文字列です。数値で使う場合は注意が必要で、「params[:select_num].to_i」とする必要があります。
その他アレンジ
セレクトボックス内の初期値について
基本的に何もしなければ、一番上に書いたoptionの内容がセレクトボックスに初期値として表示されます。
それとは別に、「selected」を使うことで、初期値を設定することも可能です。
<h4>問題数を選ぶ</h4> <select id="select_num"> <option value="5">5</option> <option value="10" selected>10</option> <option value="15">15</option> <option value="20">20</option> <option value="30">30</option> </select>
この場合「問題数を選ぶ」のセレクトボックス の最初に「10」が出てきます。
配列(変数)の中身をまとめてプルダウンに表示
以下のようにしてHTMLに<% %>を用いてrubyを書くことで、
配列(変数)に入っているデータを一気にプルダウンメニューに表示させることも可能です。
<h4>出題範囲を選ぶ</h4> <select id="select_field"> <option value="all_fields">全ての範囲から出題</option> <option value="temporary">仮免許の範囲から出題</option> <% @fields.each do |field|%> <option value="<%= field.id.to_json %>">分野別に出題:<%= field.field_name %></option> #eachで繰り返し <% end %> </select>
僕の場合「出題範囲を選ぶ」で、免許問題の「分野」を一個ずつプルダウンに入れたかったのでこのように書きました。
「@fields」に、Fieldモデルから取得した「分野」データ変数が、配列の状態で入ってます。
この場合注意すべきなのは、value値を<option>タグに当てる方法です。
コードを抜粋すると、
<option value="<%= field.id.to_json %>">分野別に出題:<%= field.field_name %></option>
ここに当たるんですが、value値を「value=”<%= field.id.to_json %>”」のように、ダブルクォーテーションで囲ったruby文にしないと反応しません。
調べた際には、「viewに埋め込む」と表現されてました。
基本的にrails開発環境で、rubyからJavaScriptへ変数や値を渡す簡単な方法は2つです。
[st-midasibox title=”rubyからJSへ値を渡す方法” fontawesome=”” bordercolor=”” color=”” bgcolor=”” borderwidth=”” borderradius=”” titleweight=”bold”]
- Gem「gon」の利用
- 上記の方法(rubyの変数を<%%>で囲い、HTMLに直接書き込んでJSで認識させる)
[/st-midasibox]
「gon」はコントローラーで生成して直接JavaScriptに渡されるイメージです。
今回の場合、ユーザーが「どの問題を何問やりたいか」という情報は、
html.erb内に書かれたセレクトボックスのみぞ知る内容なので、わざわざコントローラーを経由させて「gon」を使うより、「viewに埋め込む」をした方がいいのかなと。
その結果、どちらも使うことになりました。
まとめ
今回はセレクトボックスで、ユーザーが選択した値をJavaScriptに渡し、ajaxでコントローラにまで持っていきました。
しかし、コントローラに持ってこれたはいいものの、問題を表示させるところで少し思うようにならず、また問題点を探しています。
ajaxでの通信と表示のタイミングの関係がまだあまりつかめてません。
JS内でのajax非同期通信のタイミングと、他の関数の呼び出されるタイミングをもう少し勉強します。
以上ありがとうございました。