Tutorial: AJAX calling in Play Framework 2.3.4


In this tutorial we will discuss about the following topics of AJAX calling in Play Framework 2.3.4:

  1. Generating a Javascript router
    1. Embedded router
    2. Router resource
  2. Use of Javascript router
    1. jQuery Ajax
    2. Success/Error handler for each router
    3. Single Success/Error handler for all routers

Generating a Javascript router

The first step to using Play’s Javascript router is to generate it. The router will only expose the routes that you explicitly declare thus minimising the size of the Javascript code.

There are two ways to generate a Javascript router. One is to embed the router in the HTML page using template directives. The other is to generate Javascript resources in an action that can be downloaded, cached and shared between pages.

 ∗ Embedded router

An embedded router can be generated using the @javascriptRouter directive inside a Scala template. This is typically done inside the main decorating template.

Follow the following steps to generate embedded router in the your application:

Step 1: Update and Add new action called ajaxCall in your Application.scala file.

/**
 * This action is used to serve Home page of the application
 *
 * @return
 */
def index = Action { implicit request =>
  Ok(views.html.index("Your new application is ready."))
}

/**
 * This action is used to handle Ajax request
 *
 * @return
 */
def ajaxCall = Action { implicit request =>
  Ok("Ajax Call!")
}

Step 2: Add the above action entry in conf/routes file.

GET   /ajax-call          controllers.Application.ajaxCall

Step 3: Update index.scala.html with following code.

@(message: String)(implicit req: RequestHeader)

@main("Welcome to Play") {

    @message

}

Step 4: Create new js file public/javascripts/app.js to implement Ajax calling

$(function() {

    ajaxCall();

});

var ajaxCall = function() {
    var ajaxCallBack = {
        success : onSuccess,
        error : onError
    }

    jsRoutes.controllers.Application.ajaxCall().ajax(ajaxCallBack);
};

var  onSuccess = function(data) {
    alert(data);
}

var onError = function(error) {
    alert(error);
}

Step 5: Update following code in main.scala.html file to generate embedded Javascript router

@(title: String)(content: Html)(implicit req: RequestHeader)

<!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="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
        
        <!-- Embedded Javascript router -->
        @helper.javascriptRouter("jsRoutes")(
              routes.javascript.Application.index,
              routes.javascript.Application.ajaxCall
        )
        
        <script src="@routes.Assets.at("javascripts/app.js")" type="text/javascript"></script>
    </head>
    <body>
        @content        
    </body>
</html>

The first parameter is the name of the global variable that the router will be placed in. The second parameter is the list of Javascript routes that should be included in this router. In order to use this function, your template must have an implicit RequestHeader in scope. For example this can be made available by adding (implicit req: RequestHeader) to the end of your parameter declarations.

Step 6: Run the application from the console

saurabh@knoldus:~/projects/knoldus/ajax-with-play$ activator
[info] Loading project definition from /home/saurabh/projects/knoldus/ajax-with-play/project
[info] Set current project to ajax-with-play (in build file:/home/saurabh/projects/knoldus/ajax-with-play/)
[ajax-with-play] $ run

--- (Running the application from SBT, auto-reloading is enabled) ---

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

(Server started, use Ctrl+D to stop and go back to the console...)

Step 7: Open the browser the hit the URL: http://localhost:9000/

ajax-with-play

Source code from the browser

<!DOCTYPE html>

<html>
    <head>
        <title>Welcome to Play</title>
        <link rel="stylesheet" media="screen" href="/assets/stylesheets/main.css">
        <link rel="shortcut icon" type="image/png" href="/assets/images/favicon.png">
        
        <script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
        
        <!-- Embedded Javascript router -->
        <script type="text/javascript">
            var jsRoutes = {}; (function(_root){
        var _nS = function(c,f,b){var e=c.split(f||"."),g=b||_root,d,a;for(d=0,a=e.length;d<a;d++){g=g[e[d]]=g[e[d]]||{}}return g}
        var _qS = function(items){var qs = ''; for(var i=0;i<items.length;i++) {if(items[i]) qs += (qs ? '&' : '') + items[i]}; return qs ? ('?' + qs) : ''}
        var _s = function(p,s){return p+((s===true||(s&&s.secure))?'s':'')+':\/\/'}
        var _wA = function(r){return {ajax:function(c){c=c||{};c.url=r.url;c.type=r.method;return jQuery.ajax(c)}, method:r.method,type:r.method,url:r.url,absoluteURL: function(s){return _s('http',s)+'localhost:9000'+r.url},webSocketURL: function(s){return _s('ws',s)+'localhost:9000'+r.url}}}
        _nS('controllers.Application'); _root.controllers.Application.index =
              function() {
              return _wA({method:"GET", url:"\/"})
              }
           
        _nS('controllers.Application'); _root.controllers.Application.ajaxCall =
              function() {
              return _wA({method:"GET", url:"\/" + "ajax-call"})
              }
           
        })(jsRoutes)
                  
        </script>
        
        <script src="/assets/javascripts/app.js" type="text/javascript"></script>
    </head>
    <body>
        Your new application is ready.
    </body>
</html>

∗ Router resource

A router resource can be generated by creating an action that invokes the router generator. It has a similar syntax to embedding the router in a template. We can generate router resource with the help of following steps:

Step 1: Create a Scala object as Controller called controllers/JavascriptRoute.scala

package controllers

import play.api.Routes
import play.api.mvc.Action
import play.api.mvc.Controller
import play.api.mvc.EssentialAction
import play.core.Router.JavascriptReverseRoute
import play.core.Router._
import routes.javascript.Application.index
import routes.javascript.Application.ajaxCall

object JavascriptRoute extends Controller {

  /* Application related JavascriptReverse Route will goes here */
  val appRoutes: List[JavascriptReverseRoute] = List(index, ajaxCall)

  /* All JavascriptReverse Route will combine here */
  val javascriptRouters = appRoutes

  /**
   * This is use to generate JavascriptReverseRoute for all provided actions
   *
   * @return
   */
  def javascriptRoutes: EssentialAction = Action { implicit request =>
    import routes.javascript._
    Ok(Routes.javascriptRouter("jsRoutes")(javascriptRouters: _*)).as("text/javascript")
  }

}

Step 2: Add the following code it conf/routes file

#Javascript Routes
GET   /javascriptRoutes   controllers.JavascriptRoute.javascriptRoutes

Step 3: Now we can include it as a resource in our templates views/main.scala.html:

<script type="text/javascript" src="@routes.JavascriptRoute.javascriptRoutes"></script>

∗ Use of Javascript router

Using the javascript router with jQuery is same like writing a normal jQuery function but Play provides some more feature to make it more easier using Javascript router.

∗ jQuery Ajax

Using jQuery as an example, making a call is as simple as:

To know more about jQuery ajax: here

var testAjax = jsRoutes.controllers.Application.ajaxCall();
$.ajax({
   url: testAjax.url
}).done(function() {
   $( "body" ).append( "done" );
}).fail(function() {
   $( "body" ).append( "fail" );
});

 ∗ Success/Error handler for each router

Here we can define callback function for each router.

var ajaxCall = function() {
    var ajaxCallBack = {
        success : onSuccess,
        error : onError
    }

    jsRoutes.controllers.Application.ajaxCall().ajax(ajaxCallBack);
};

var  onSuccess = function(data) {
    alert(data);
}

var onError = function(error) {
    alert(error);
}

∗ Single Success/Error handler for all routers

var ajaxSuccess = function(action, data) {
    $("body").append("<br/>");
    $("body").append(action + " " + data);
};

var ajaxError = function(action, error) {
    alert(action + " : " +error);
}

var renderAjaxOne = function() {
    var ajaxCallBack = {
        success : function(data) {
            ajaxSuccess("AJAX 1:", data);
        },
        error : function(error) {
            ajaxError("AJAX 1:", error);
        }
    }

    jsRoutes.controllers.Application.ajaxCall().ajax(ajaxCallBack);
};

var renderAjaxTwo = function() {
    var ajaxCallBack = {
        success : function(data) {
            ajaxSuccess("AJAX 2:", data);
        },
        error : function(error) {
            ajaxError("AJAX 2:", error);
        }
    }

    jsRoutes.controllers.Application.ajaxCall().ajax(ajaxCallBack);
};

To explore more check the Github code: here

This entry was posted in AJAX, JavaScript, jQuery, Play Framework, Scala, Web and tagged , , , , , . Bookmark the permalink.

4 Responses to Tutorial: AJAX calling in Play Framework 2.3.4

  1. Reblogged this on Play!ng with Scala and commented:

    Cool AJAX integration with Play 2.3.4

  2. dejoong says:

    how this is achieve by play java?

  3. Pingback: Tutorial: AJAX calling in Play Framework 2.3.4 | Saurabh Chopra

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s