Skip to content

Commit 16747c1

Browse files
committed
mini-forms sample
1 parent e731e12 commit 16747c1

19 files changed

Lines changed: 2899 additions & 0 deletions

File tree

samples/mini-forms/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
logs
2+
project/project
3+
project/target
4+
target
5+
tmp

samples/mini-forms/README

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
This is a dummy application presenting several typical form usages. It demonstrates:
2+
3+
- Writing complex forms with validation.
4+
- Handling forms with dynamically repeated values.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package controllers
2+
3+
import play.api._
4+
import play.api.mvc._
5+
6+
import views._
7+
8+
object Application extends Controller {
9+
10+
def index = Action {
11+
Ok(html.index());
12+
}
13+
14+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package controllers
2+
3+
import play.api._
4+
import play.api.mvc._
5+
import play.api.data._
6+
import play.api.data.Forms._
7+
import play.api.data.validation.Constraints._
8+
9+
import views._
10+
11+
import models._
12+
13+
import play.api.i18n._
14+
import scala.jsvalidation.PlayLMS._
15+
16+
object Comments extends Controller {
17+
18+
val commentForm: Form[Comment] = Form(
19+
mapping(
20+
"firstname" -> nonEmptyText,
21+
"lastname" -> nonEmptyText,
22+
"company" -> optional(text),
23+
"email" -> email,
24+
"phone" -> optional(text verifying jsPattern("""[0-9.+]+""", "constraint.phone", "A valid phone number is required")),
25+
"message" -> nonEmptyText
26+
)(Comment.apply)(Comment.unapply)
27+
)
28+
29+
lazy val js = generateJS(Messages(_), twitterBootstrap = true, playDefaults = true)(commentForm.mapping)
30+
31+
/**
32+
* Display an empty form.
33+
*/
34+
def form = Action {
35+
Ok(html.comment.form(js, commentForm));
36+
}
37+
38+
/**
39+
* Display a form pre-filled with an existing Comment.
40+
*/
41+
def editForm = Action {
42+
val existingComment = Comment(
43+
"Nada", "Amin", Some("EPFL"), "namin@alum.mit.edu", Some("41.79.275.15.35"), "I love Scala."
44+
)
45+
Ok(html.comment.form(js, commentForm.fill(existingComment)))
46+
}
47+
48+
/**
49+
* Handle form submission.
50+
*/
51+
def submit = Action { implicit request =>
52+
commentForm.bindFromRequest.fold(
53+
errors => BadRequest(html.comment.form(js, errors)),
54+
comment => Ok(html.comment.summary(comment))
55+
)
56+
}
57+
58+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package models
2+
3+
case class Comment(
4+
firstname: String,
5+
lastname: String,
6+
company: Option[String],
7+
email: String,
8+
phone: Option[String],
9+
message: String
10+
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
@(js: String => String, commentForm: Form[Comment])
2+
3+
@import helper._
4+
@import helper.twitterBootstrap._
5+
6+
@title = {
7+
Add a new comment <small><a href="@routes.Comments.editForm">Or edit an existing comment</a></small>
8+
}
9+
10+
@main(title, nav = "comment") {
11+
<script>@Html(js("#commentForm"))</script>
12+
13+
@if(commentForm.hasErrors) {
14+
<div class="alert-message error">
15+
<p><strong>Oops</strong> Please fix all errors</p>
16+
</div>
17+
}
18+
19+
@helper.form(action = routes.Comments.submit, args = 'id -> "commentForm") {
20+
21+
<fieldset>
22+
<legend>Send us a <em>nice</em> comment!</legend>
23+
24+
@inputText(
25+
commentForm("firstname"),
26+
'_label -> "First name"
27+
)
28+
29+
@inputText(
30+
commentForm("lastname"),
31+
'_label -> "Last name"
32+
)
33+
34+
@inputText(
35+
commentForm("company"),
36+
'_label -> "Company"
37+
)
38+
39+
@inputText(
40+
commentForm("email"),
41+
'_label -> "Email"
42+
)
43+
44+
@inputText(
45+
commentForm("phone"),
46+
'_label -> "Phone"
47+
)
48+
49+
@inputText(
50+
commentForm("message"),
51+
'_label -> "Message"
52+
)
53+
</fieldset>
54+
55+
<div class="actions">
56+
<input type="submit" class="btn primary" value="Send">
57+
<a href="@routes.Application.index" class="btn">Cancel</a>
58+
</div>
59+
60+
}
61+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@(comment: Comment)
2+
3+
@main(Html("Comment sent!"), nav = "comment") {
4+
5+
<h2>@comment.firstname @comment.lastname</h2>
6+
7+
<h6>Company</h6>
8+
9+
<p>
10+
@comment.company.getOrElse { <em>Not specified</em> }
11+
</p>
12+
13+
<h6>Email</h6>
14+
15+
<p>
16+
@comment.email
17+
</p>
18+
19+
<h6>Phone</h6>
20+
21+
<p>
22+
@comment.phone.getOrElse { <em>Not specified</em> }
23+
</p>
24+
25+
<h6>Message</h6>
26+
27+
<p>
28+
@comment.message
29+
</p>
30+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
@main(Html("Form samples")) {
2+
<h2>Comment form</h2>
3+
4+
<p>
5+
Demonstrate a comment form checked on both server and client sides.
6+
</p>
7+
8+
<p>
9+
<a class="btn" href="@routes.Comments.form">View sample »</a>
10+
</p>
11+
12+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
@(title: Html, nav: String = "")(content: Html)
2+
3+
<!DOCTYPE html>
4+
5+
<html>
6+
<head>
7+
<title>Form samples</title>
8+
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/bootstrap.css")">
9+
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
10+
<link rel="shortcut icon" type="image/png" href="@routes.Assets.at("images/favicon.png")">
11+
<script src="http://code.jquery.com/jquery-latest.js"></script>
12+
<script type="text/javascript" src="http://jzaefferer.github.com/jquery-validation/jquery.validate.js"></script>
13+
</head>
14+
<body>
15+
16+
<div class="topbar">
17+
<div class="fill">
18+
<div class="container">
19+
<a class="brand" href="@routes.Application.index()">Forms</a>
20+
<ul class="nav">
21+
<li class="@("active".when(nav == "comment"))">
22+
<a href="@routes.Comments.form">Comments</a>
23+
</li>
24+
</ul>
25+
</div>
26+
</div>
27+
</div>
28+
29+
<div class="container">
30+
31+
<div class="content">
32+
33+
<div class="page-header">
34+
<h1>@title</h1>
35+
</div>
36+
37+
<div class="row">
38+
<div class="span14">
39+
@content
40+
</div>
41+
</div>
42+
43+
</div>
44+
45+
<footer>
46+
<p>
47+
<a href="http://www.playframework.org">www.playframework.org</a>
48+
</p>
49+
</footer>
50+
51+
</div>
52+
53+
</body>
54+
</html>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# This is the main configuration file for the application.
2+
# ~~~~~
3+
4+
# Secret key
5+
# ~~~~~
6+
# The secret key is used to secure cryptographics functions.
7+
# If you deploy your application to several instances be sure to use the same key!
8+
application.secret="HaD4G7mboGeN=dyx=^KxRaj4oVTsGxbM>P;xHg]^uu[l/JxjHQR^fqsMQYTSB>vo"
9+
10+
# Global object class
11+
# ~~~~~
12+
# Define the Global object class for this application.
13+
# Default to Global in the root package.
14+
# global=Global
15+
16+
# Database configuration
17+
# ~~~~~
18+
# You can declare as many datasources as you want.
19+
# By convention, the default datasource is named `default`
20+
#
21+
# db.default.driver=org.h2.Driver
22+
# db.default.url="jdbc:h2:mem:play"
23+
# db.default.user=sa
24+
# db.default.password=
25+
#
26+
# You can expose this datasource via JNDI if needed (Useful for JPA)
27+
# db.default.jndiName=DefaultDS
28+
29+
# Evolutions
30+
# ~~~~~
31+
# You can disable evolutions if needed
32+
# evolutions=disabled
33+
34+
# Ebean configuration
35+
# ~~~~~
36+
# You can declare as many Ebean servers as you want.
37+
# By convention, the default server is named `default`
38+
#
39+
# ebean.default="models.*"
40+
41+
# Logger
42+
# ~~~~~
43+
# You can also configure logback (http://logback.qos.ch/), by providing a logger.xml file in the conf directory .
44+
45+
# Root logger:
46+
logger.root=ERROR
47+
48+
# Logger used by the framework:
49+
logger.play=INFO
50+
51+
# Logger provided to your application:
52+
logger.application=DEBUG
53+

0 commit comments

Comments
 (0)