vaguely

和歌山に戻りました。ふらふらと色々なものに手を出す毎日。

Ajaxに触れてみる

今回はちょっと脇道にそれて、SinatraAjaxを試してみたお話。

はじめに

ボタンを押すなど、何か操作をした場合にページ遷移せずに表示内容を変更してみたい。
ということで、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
  1. $.ajaxの部分からがAjax処理の記述部分です。
  2. 「async」をtrueにして非同期処理を有効にします。
  3. 指定のURLにアクセスして、json形式のデータを取得します(後述のapp.rbで生成します)。
  4. アクセスに成功した場合、「$('#square').css」でid「#square」を持ったタグにCSSを設定します。
  5. 「$('#square').html」で、jsonから取得したHTML(ボタン)を追加します。
  6. エラーが発生した場合はアラートを表示します。

※ 上記処理ではメソッドを呼ぶと、前のボタンは消えますが、「$('#square').append("

test
")」と記述するとメソッド実行のたびに「test」の文字列が追加されていきます。

コントローラ

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

CSS

Coffeescript

Rubyの改行