第4回: Ajax (1)
2012/03/11
前回は、CoffeeScriptの関数の使い方について書きました。
今回はお待ちかね、Ajaxです。
ダブルクリックして正方形を表示させたら、その位置をデータベースに記録して永続化することにしましょう。
正方形をドラッグして位置を変更した場合の処理については、次の回で説明します。
Blockモデルの生成
まず、Blockモデルを生成します。
% rails g model block x:integer y:integer % rake db:migrate
blocksコントローラの実装
次に、blocksコントローラを生成します。
% rails g controller blocks
config/routes.rb
を修正。
Toraja::Application.routes.draw do root to: "top#index" resources :blocks, only: [ :create ] end
app/controllers/blocks_controller.rb
を修正。
class BlocksController < ApplicationController def create block = Block.create!(params[:block]) render text: block.id end end
データベースに登録された正方形を画面に表示
app/controllers/top_controller.rb
を修正。
class TopController < ApplicationController def index @blocks = Block.all end end
app/views/top/index.html.erb
を修正。
<div id="canvas"> <% @blocks.each do |block| %> <%= content_tag(:div, nil, class: "block", style: "left: #{block.x}px; top: #{block.y}px") %> <% end %> </div>
content_tag
メソッドでキャンバスの中に正方形を配置しています。
正方形の位置をデータベースに登録
ここからが本題です。
現在、app/assets/javascripts/top.js.coffee
はこうなっています。
$ -> $("div#canvas").dblclick (e) -> [x, y] = positionOfNewBlock(e) block = $("<div class='block' style='left: #{x}px; top: #{y}px;' />"). draggable({ containment: "parent" }).css({ position: "absolute" }) $(e.target).append(block) positionOfNewBlock = (e) -> canvas = $(e.target) x = e.pageX - canvas.position().left y = e.pageY - canvas.position().top [x, y]
前半部分(1-6行目)を次のように修正してください。
$ -> $("div#canvas").dblclick (e) -> [x, y] = positionOfNewBlock(e) $.post '/blocks', block: { x: x, y: y }, (block_id) -> block = $("<div class='block' style='left: #{x}px; top: #{y}px;' />"). draggable(containment: "parent").css(position: "absolute") $(e.target).append(block) $("div.block").draggable(containment: "parent").css(position: "absolute")
最大のポイントは4行目です:
$.post '/blocks', block: { x: x, y: y }, (block_id) ->
POSTメソッドによるAjaxリクエストを行っています。リクエスト先のURLは /blocks
です。
送信されるデータは block: { x: x, y: y }
。入れ子になったハッシュ(ハッシュのハッシュ)になっています。
ブラウザがこのAjaxリクエストを行うと、blocksコントローラのcreateアクションが作動して、データベースにレコードが格納されます。
createアクションは新しく登録されたBlockオブジェクトのidを文字列で返してきます。括弧の中にある変数 block_id
にその文字列がセットされます。
Ajaxリクエストが成功すると ->
以下の3行が実行されます。
block = $("<div class='block' style='left: #{x}px; top: #{y}px;' />"). draggable(containment: "parent").css(position: "absolute") $(e.target).append(block)
変更前のコードの4-6行目とまったく同じです。ただし、2文字文インデントを増やしています。
もうひとつ追加されたのは、次のコードです。
$("div.block").draggable(containment: "parent").css(position: "absolute")
データベースに登録されている正方形についてもドラッグ可能にしています。
修正が完了したら、動作確認をしましょう。ブラウザに戻り、ページを再読込してから、キャンバスの中を適宜クリックして、正方形を登録します。ページを再読込しても登録した正方形が同じ位置に表示されればOKです。
更新情報
- ソースコードに
$("div.block").draggable(containment: "parent").css(position: "absolute")
を追加しました。また、「もうひとつ追加されたのは、次のコードです。」から「ドラッグ可能にしています。」までを追加しました。(2012/3/15)