Coder Social home page Coder Social logo

graph's Introduction

6 Minute Apps

===============

This is an introduction to building Modern Web Apps with Play Framework, Scala, CoffeeScript, and LESS

Setup

  1. Download Typesafe Activator
  2. Extract the zip and run the activator script from a non-interactive shell
  3. Your browser should open to the Activator UI: http://localhost:8888

Create a Play App

Create a new Play Framework application using the Hello Play Framework! template. This will compile the application then run it and it's tests. You can see the running application at: http://localhost:9000/

Open in an IDE

If you want to use an IDE (Eclipse or IntelliJ), click on Code, select Open, and then select your IDE. This will walk you through the steps to generate the project files and open the project. Alternatively you can edit files in the Activator UI.

Update Dependencies

In the project/Build.scala file add the following lines to the appDependencies section after the line containing javaCore:

"org.sorm-framework" % "sorm" % "0.3.8",
"com.h2database" % "h2" % "1.3.168",

This adds the SORM and H2 dependencies to the application. Refresh the page in order to reload the build definition and dependencies.

Cleanup Template Files

Remove the following files:

  • app/assets/javascripts/index.js
  • app/controllers/MainController.java
  • app/controllers/MessageController.scala
  • test/IntegrationTest.java
  • test/MainControllerTest.java
  • test/MessageControllerSpec.scala

Delete the following lines from the conf/routes file:

GET     /                           controllers.MainController.index()
GET     /message                    controllers.MessageController.getMessage()
GET     /assets/javascripts/routes  controllers.MessageController.javascriptRoutes()

Remove the following line from the app/views/main.scala.html file:

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

Verify that the app compiles without any errors.

Create a Model

Create a new directory under app named models. Create a new file named Bar.scala in the app/models directory containing:

package models

import play.api.libs.json.{JsValue, Writes, Json}
import sorm.Persisted

case class Bar(name: String)

object Bar {
  implicit val barWrites = new Writes[Bar with Persisted] {
    def writes(bar: Bar with Persisted): JsValue = {
      Json.obj(
        "id" -> bar.id,
        "name" -> bar.name
      )
    }
  }
  implicit val barReads = Json.reads[Bar]
}

import sorm._
object DB extends Instance(
  entities = Set(Entity[Bar]()),
  url = "jdbc:h2:mem:test"
)

Test the Model

Create a new file in the test directory named BarSpec.scala containing:

import models.{DB, Bar}

import org.specs2.mutable.Specification
import play.api.test._

class BarSpec extends Specification {

  "Bar" should {
    "be creatable" in new WithApplication {
      val bar = DB.save(Bar("foo"))
      bar.id must not (beNull)
      bar.name must beEqualTo ("foo")
    }
  }
  
}

In the Test tab, select Start to re-run the tests. The only test should pass.

Create a Controller

In the app/controllers directory create a new file named Application.scala containing:

package controllers

import models.{DB, Bar}
import models.Bar._

import play.api.libs.json.Json
import play.api.mvc.{Action, Controller}


object Application extends Controller {
  
  def index = Action {
    Ok(views.html.index("hello, world"))
  }
  
  def bars = Action {
    val bars = DB.query[Bar].fetch()
    Ok(Json.toJson(bars))
  }
  
  def addBar = Action(parse.json) { request =>
    val bar = DB.save(request.body.as[Bar])
    Ok(Json.toJson(bar))
  }
  
}

Map the routes

In the conf/routes file, add the following at line 5:

GET     /                           controllers.Application.index
GET     /bars                       controllers.Application.bars
POST    /bars                       controllers.Application.addBar

Test the Controller

Create a new file in the test directory named ApplicationSpec.scala containing:

package test

import controllers.Application
import models.Bar

import org.specs2.mutable._
import play.api.libs.json.Json
import play.api.test._
import play.api.test.Helpers._

class ApplicationSpec extends Specification {
    
  "Application" should {
    
    "add a bar" in new WithApplication {
      val addBar = Application.addBar()(FakeRequest(POST, "/bars").withBody(Json.parse("""{"name": "foo"}""")))
      status(addBar) must equalTo(OK)
      Json.parse(contentAsString(addBar)).as[Bar].name must beEqualTo ("foo")
    }
    
    "get all bars" in new WithApplication {
      val bars = Application.bars()(FakeRequest(GET, "/bars"))
      status(bars) must equalTo(OK)
      Json.parse(contentAsString(bars)).as[Seq[Bar]].length must beGreaterThan (0)
    }
    
  }
}

In the Test tab, select Start to re-run the tests. All three tests should pass.

HTML UI

In the app/views/index.scala.html file, replace the contents beneath the script tag with:

    <div class="container">
        <ul id="bars"></ul>
        <form id="barForm" method="post" action="/bars">
            <label for="barName">Name</label>
            <input id="barName" required>
            <button>Add Bar</button>
        </form>
    </div>

Verify that the app now contains the form: http://localhost:9000/

CoffeeScript UI Logic

Create a new file in the app/assets/javascripts/ directory named index.coffee containing:

getBars = () ->
  $.get "/bars", (bars) ->
    $("#bars").empty()
    $.each bars, (index, bar) ->
      $("#bars").append $("<li>").text bar.name

$ ->
  getBars()
  $("#barForm").submit (event) ->
    event.preventDefault()
    $.ajax
      url: event.target.action
      type: event.target.method
      contentType: "application/json"
      data: JSON.stringify({name: $("#barName").val()})
      success: () ->
        getBars()
        $("#barName").val("")

Verify the app now works: http://localhost:9000/

graph's People

Contributors

vertexshader256 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.