LoginSignup
19
18

More than 5 years have passed since last update.

Play framework2(Scala)でAjaxによる非同期通信

Last updated at Posted at 2014-04-20

Play framework2(Scala)で、Ajaxを使って画面遷移せずにコメントを投稿するプログラムです。
JavaScriptルーティングを使って実装します。

以下、実装。

コントローラのApplication.scala

Application.scala
package controllers

import play.api._
import play.api.mvc._
import models.Comment

object Application extends Controller {

  def index = Action {
    Ok(views.html.index(Comment.all()))
  }

  def postComment(comment: String) = Action { implicit request =>
    Comment.insertDB(comment)
    Ok
  }

  def javascriptRoutes = Action { implicit request =>
    import routes.javascript._
    Ok(
       Routes.javascriptRouter("jsRoutes")(routes.javascript.Application.postComment)
    ).as("text/javascript")
  }
}

ビューのmain.scala

main.scala
@(title: String)(content: Html)

<!DOCTYPE html>
<html>
    <head>
        <title>@title</title>
        <link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
        <link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
        <script src="@routes.Assets.at("javascripts/jquery-1.9.0.min.js")" type="text/javascript"></script>
        <script type="text/javascript" src="@routes.Application.javascriptRoutes"></script>
    </head>
    <body>
        @content
    </body>
</html>

ルータをヘッダに書き、読み込ませます。

ビューのindex.scala

index.scala
@(comments: List[Comment])

@main("Ajax Comment") {

<form class="form-inline" id="comment-form">
  <input type="text" id="input-comment" placeholder="comment" />
  <button type="submit" id="comment-submit">post</button>
</form>

<!-- コメントを表示 -->
<ul id="comments">
  @comments.map { comment =>
    <li>@comment.comment</li>
  }
<ul>

<script>
$('#comment-form').submit(function(event) {
  event.preventDefault();
  var comment = $("#input-comment").val();
  jsRoutes.controllers.Application.postComment(comment).ajax({
    // 送信したらボタンを使用不可にし二重投稿を防ぐ
    beforeSend: function() {
      $("#comment-submit").attr('disabled', true);
    },
    // 完了したらボタン使用不可を解除する
    complete: function() {
      $("#comment-submit").attr('disabled', false);
    },
    // 投稿が成功したら新しいコメントを表示する
    success: function(datetime) {
      $("#input-comment").val("");
      $('#comments').append("<li>" + comment + "</li>")
    },
    error: function() {
      alert("error")
    }
  })
});
</script>

}

モデルのComment.scala

Comment.scala
package models

import anorm._
import anorm.SqlParser._
import play.api.db._
import play.api.Play.current

case class Comment(id: Long, comment: String)

object Comment {

  def all(): List[Comment] = DB.withConnection { implicit c =>
    SQL("select * from comment").as(comment *)
  }

  def insertDB(comment: String) {
    DB.withConnection { implicit c =>
      SQL("""
          insert into comment (comment)
          values ({comment})
          """
      ).on(
        'comment -> comment
      ).executeUpdate()
    }
  }

  val comment = {
    get[Long]("id") 
    get[String]("comment") map {
      case id  comment => Comment(id, comment)
    }
  }
}

routes

# Routes
# This file defines all application routes (Higher priority routes first)
# ‾‾‾‾

# Home page
GET     /                           controllers.Application.index

POST    /comment                    controllers.Application.postComment(comment: String)

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)

GET     /javascriptRoutes           controllers.Application.javascriptRoutes

それ以外のファイルはgithubにあげています。

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18