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

jQuery Mobile でフォームを submit 後にリダイレクトするとロケーションが変わらない

javascript ruby

jQuery Mobile を使った Web アプリ開発で、

  1. フォームの submit で非同期に POST リクエストを送信
  2. サーバー側でフォームデータを処理した後リダイレクトを返す
  3. クライアント側でリダイレクト先にページ遷移

という処理を実装するとき、data-role="page" を指定したタグに、data-url="ページのURL" も指定する必要がある。data-url を指定していないと、「画面は変わるけど、アドレスバーに表示されている URL は変わらない」という動きをしてしまう。

サンプルコードは次の通り。

# coding: utf-8
require "sinatra"

@@greets = []

get "/" do
  @greets = @@greets
  erb :index
end

get "/greet" do
  erb :new
end

post "/greet" do
  @@greets << params[:greet]
  redirect "/"
end

__END__
@@layout
<!DOCTYPE html>
<html>
  <head>
    <title>RedirectSample</title>
    <link rel="stylesheet" href="/jquery.mobile-1.0.1.css" />
    <script type="text/javascript" src="/jquery-1.6.2.js"></script>
    <script type="text/javascript" src="/jquery.mobile-1.0.1.js"></script>
  </head>
  <body>
    <%= yield %>
  </body>
</html>

@@index
<%
=begin
data-url を設定しておかないと、リダイレクでこのページに移動したとき、
ロケーションが変更されない。
=end
%>
<div data-role="page" data-url="/">
  <div data-role="header">
    <h1>Index</h1>
    <a data-role="button"
       data-icon="plus"
       data-iconpos="notext"
       class="ui-btn-right"
       href="/greet">Greet</a>
  </div>
  <div data-role="content">
    <ul data-role="listview">
      <% @greets.each do |g| %>
        <li><%= g %></li>
      <% end %>
    </ul>
  </div>
</div>

@@new
<div data-role="page" data-add-back-btn="true">
  <div data-role="header">
    <h1>New</h1>
  </div>
  <div data-role="content">
    <form method="POST" action="/greet">
      <input type="text" name="greet"/>
      <input type="submit" value="Post"/>
    </form>
  </div>
</div>