読者です 読者をやめる 読者になる 読者になる

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の改行