Ajax非同期通信をRailsで使う
先週散々頭を悩まされ続けてきた、「選択した会社名に応じて売上発生原因の項目をajaxで変更する。」という課題を何とかするために、丸一日使って、同じような仕組みを実装してみた。
お題を少し変えて、「大学名に応じて、選択する学部名を変える」というものにした。
(function (){ $("#univerisities").change(function(){ var value = $("#univerisities").val(); function getParam(){return $.ajax({ url: "/articles/ajax_department", type: "GET", data: {id: value}, dataType: "script", success: function(data) {alert("success");}, error: function(data) {alert("error");} });} getParam().done(function(result) { console.log(result); }).fail(function(result) { console.log(result) }); }) })
JQueryを使って、プルダウンメニューの変更探知もかなりシンプルに書くことが出来る。また、非同期の通信、つまり通信の終了時の動作は自分で書くことを求められ、それがgetParam.done()になっている。
で、このJSのコードでコントローラのアクションを叩き、これによって、プルダウンメニューのオプションを変えるのに必要なアクション名.js.erbが返される。
respond_to do |format| format.js end
js.erbはサーバー側で、erb部分が適当な値にレンダリングされ、純粋なjavascriptとしてクライアント側に返される。
$("#replace").html('<%= j select_tag 'univerisities', grouped_options_for_select(@departments,nil,prompt: "学部を入力してください。") %>')
上のコードの場合、@departmentsはコントローラで取得したJSONの配列に置き換わる。
この時、select_tagの前に「j」を付けないと「invalid or unexpected token」となる。このエラーは別のファイルとして読み込んでいる場合、コンソールにも表示されない。自分はjs.erb自体が読み込まれていないのではないかと悩み、これに3時間ほど頭を悩ませた。
プルダウンメニューはreplaceというdivで囲ってあり、それをターゲットとしてhtmlの書き換えを行っている。
ちなみに、JSONの配列は
SELECT_UNIVERSITIES = [["大学",[ ["明治大学",1], ["立教大学",2], ["青山学院大学",3], ["法政大学",4], ["中央大学",5], ["学習院大学",6] ] ]]
大項目が一つしかない場合でも、それ一つを配列の1つ目として扱わなくてはならない。また、複数の選択肢全体で一つの配列を形成していなくてはならない。
これを売上計上原因に応用するとこんな感じになり、
SalesReasons = [ ["増加",[]], ["売上",[["テスト売上",1],["その他",2]]], ["減少",[]], ["売上",[["課税売上高",1],["その他",2]]] ]
それをselect_tagとgrouped_options_for_selectタグを使って分類するとこんな感じで仕上がる。
このJSONはJSON fomatterを使うと文法ミスにされるんだけど、railsで読み込ませてみたらちゃんと使えた。