今回はちょっと脇道にそれて、SinatraでAjaxを試してみたお話。
はじめに
ボタンを押すなど、何か操作をした場合にページ遷移せずに表示内容を変更してみたい。
ということで、jQueryを使って非同期処理をすることにしました。
今回やったこと
ページ上に四角とボタンを表示して、ボタンを押すと四角の色と大きさを変更する
ページ構成
プロジェクトのルートディレクトリ Lapp.rb Lconfig.ru LGemfile Lvendor Lbundle L... LViews Llayout.slim Lsquare.slim Ljs Ljavascript.coffee
jQuery
公式サイトからmin.jsを読み込んで使用しています。
layout.slim
DOCTYPE html head meta charset="utf-8" title Asynchronous script src="http://code.jquery.com/jquery-2.1.3.min.js" script src="/js/javascript.js" body main == yield
views
今回は特定のidを持ったタグに対して、javascriptから要素を追加するため、とてもシンプルです。
square.slim
article#square
Ajax
さていよいよ本題。
画面(views)上でボタンを押したら、以下のメソッドを呼び出します。
javascript.coffee
@changeSize = (intSizeNum)-> $.ajax async: true type: 'GET', url: 'http://localhost:9292/size/' + intSizeNum datatype: 'json' success: (json) -> $('#square').css "height": json.square_height "width": json.square_width "background-color": json.square_bgcolor $('#square').html(json.button) error: (xhr, status, error) -> alert status
- $.ajaxの部分からがAjax処理の記述部分です。
- 「async」をtrueにして非同期処理を有効にします。
- 指定のURLにアクセスして、json形式のデータを取得します(後述のapp.rbで生成します)。
- アクセスに成功した場合、「$('#square').css」でid「#square」を持ったタグにCSSを設定します。
- 「$('#square').html」で、jsonから取得したHTML(ボタン)を追加します。
- エラーが発生した場合はアラートを表示します。
※ 上記処理ではメソッドを呼ぶと、前のボタンは消えますが、「$('#square').append("
コントローラ
require 'coffee-script' require 'sinatra' require 'sinatra/base' require 'sinatra/reloader' require 'slim' class MainApp < Sinatra::Base get '/' do slim :square end get '/size/:name' do intSizeNum = params[:name].to_i case intSizeNum when 0 s_height = "100px" s_width = "100px" s_bgcolor = "#0FEE21" b_action_num = "1" b_value = "Large" b_style = "border-style: none; margin: 30% 30%; height: 40px; width:40px;" when 1 s_height = "500px" s_width = "500px" s_bgcolor = "#00FF00" b_action_num = "0" b_value = "x" b_style = "background-color: #FF0000; border-radius: 50%; border-style: none; color: #FFFFFF; height: 20px; width: 20px;" end button = "< input type=\"button\" onclick=\"changeSize(" + b_action_num + ")\" value=\"" + b_value + "\" style=\"" + b_style + "\" >" content_type :json data = { square_height: s_height, square_width: s_width, square_bgcolor: s_bgcolor, button: button} data.to_json end get '/js/javascript.js' do coffee :'js/javascript' end end
json生成部分がゴチャついてますが...。
重要なところは「get '/size/:name' do」。
javascript.coffeeから非同期でアクセスされ、jsonデータを生成してそれを返しています。
jsonの生成は、「content_type :json」でデータの種類を指定し、javascriptで扱いたいデータをセットします。
それを「.to_json」でjsonに変換すると。シンプルで良い感じです。
javascript側ではsuccessの時に、取得したjsonデータが取得できるので、「json.square_height」のような形でコントローラから渡したデータを使用できます。
注意点など
ajaxの処理でコントローラにアクセスできるから、とapp.rbからsquare.slimに渡しているデータの中身を変更しても、表示中のページに反映はされません。
また今日ググってみた感じだと、ajaxの処理からslimを扱うことはできないようなので、今回の内容だとあまりslimを使っている恩恵が得られない気はします。
コントローラでhtml(ボタン)を生成している辺りも、もう少しシンプルに出来ると良いのですが...。
ページロード時のjavascript実行
実は上記のコードをコピペしただけだと、四角の表示はできてもボタンが表示されず、動作できないと思います。
ページを読み込むときに、ボタン押下時に実行するメソッド「changeSize」を実行することでボタンを表示してやります。
javascript.coffee
$(window). on "load" , -> changeSize.call @, 0
app.rbでの改行
app.rbに限りませんが、rubyでコードの途中で改行しようと思った時に、以下のようにするとエラーになります。
test = "test" + " No1"
「+」記号を1行目に移し、「+」記号の後に改行すると問題なく動作します。
test = "test" + " No1"
「,」なども同じで、他の言語で書くときの癖でつい記号を頭に持ってくるため、あれ?となりがちです。
参考
Ajax
- Sinatra & jQueryで、JSONを扱ったAjaxをしてみよう - 大学生からはじめる Web 開発
- jQueryでajaxを投げるメモ [俺の備忘録]
- Simple Tabs with AJAX and jQuery « Design Chemical - jQuery, Wordpress, Tutorials & Plugins
- jQuery with CoffeeScript - CSS-Tricks
- 複数のプロパティの値をまとめて設定 - スタイルシートの操作 - jQueryの使い方