前回、非常に苦労して Pjax を試しました。
ページ移動を非同期で行えるようになったので、次はフォームの submit 後も同じようにページを移動したい、と考えてしまうのは当然ですよね。これも Pjax でやりたい。
jquery.pjax のソースコードを見たところ、a タグなどの click イベントを捕まえて、非同期でページ更新を行っていました。フォームの submit イベントには対応していません。さて、どうしよう。
Pjax の $.pjax メソッドを使えば、$.ajax みたいに POST リクエストを送信できるので、これを使って自前でフォームデータを送信すれば上手くいきそうです。
<!DOCTYPE html> <html> <head> <title>PjaxSample</title> </head> <body> <div id="header"> <h1>PjaxSample</h1> </div> <!--PJAX で #main の中が書き変わる--> <div id="main"> <form id="sample-form" method="POST" action="{{ url_for('greet') }}"> <label>名前</label> <input type="text" name="name"/> <input type="submit" value="Greet"/> </form> </div> <script type="text/javascript" src="{{ url_for('static', filename='jquery-1.6.2.js') }}"></script> <script type="text/javascript" src="{{ url_for('static', filename='jquery.pjax.js') }}"></script> <script type="text/javascript"> $("#sample-form").submit(function(e) { if ($.support.pjax) { // PJAX が使えるブラウザのとき var url = $(this).attr("action"); var name = $(this).find("input[name='name']").first().val(); $.pjax({ timeout: 3600, url: url, container: "#main", type: "POST", data: { _pjax: true, name: name } }); return false; } else { return true; } }); </script> </body> </html>
サーバーサイドは Python + Flask でさくっと実装。こんな感じ。
#!/usr/bin/env python from google.appengine.ext.webapp import util from flask import ( Flask, render_template, request, ) app = Flask(__name__) @app.route("/") def index(): return render_template("index.html") @app.route("/greet", methods=["POST"]) def greet(): name = request.form["name"] if "X-PJAX" in request.headers: return "Hello, %s! (Pjax)" % name else: return "Hello, %s!" % name if __name__ == '__main__': util.run_wsgi_app(app)
これで一応、フォームの submit 後に Pjax を使って非同期にページを更新できました。しかし、フォームデータを自力で送信してるので、項目が多くなったら地獄になるのは目に見えています。工夫が必要。
そういえば、jQuery Mobile もフォームを submit するとページを非同期で更新していた気がします。参考にしてみるといいかもしれませんね。