Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #766 from takezoe/forms-helpers-for-scalate
Add helpers to render forms in Scalate templates
- Loading branch information
Showing
3 changed files
with
103 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
101 changes: 101 additions & 0 deletions
101
scalate/src/main/scala/org/scalatra/scalate/ScalatraFormsHelpers.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package org.scalatra.scalate | ||
|
||
import org.fusesource.scalate.servlet.ServletRenderContext | ||
import org.scalatra.MultiParams | ||
|
||
/** | ||
* Supplies helper methods to render forms in Scalate templates. | ||
*/ | ||
trait ScalatraFormsHelpers { self: ServletRenderContext => | ||
|
||
private val RequestAttributeParamsKey = "org.scalatra.forms.params" | ||
private val RequestAttributeErrorsKey = "org.scalatra.forms.errors" | ||
|
||
/** | ||
* Render a text field. | ||
*/ | ||
def text(name: String, attributes: (String, String)*): Unit = { | ||
unescape(s"""<input type="text" name="${escape(name)}" value="${escape(param(name))}" ${attrs(attributes: _*)}>""") | ||
} | ||
|
||
/** | ||
* Render a password field. | ||
*/ | ||
def password(name: String, attributes: (String, String)*): Unit = { | ||
unescape(s"""<input type="password" name="${escape(name)}" ${attrs(attributes: _*)}>""") | ||
} | ||
|
||
/** | ||
* Render a textarea. | ||
*/ | ||
def textarea(name: String, attributes: (String, String)*): Unit = { | ||
unescape(s"""<textarea name="${escape(name)}" ${attrs(attributes: _*)}>${escape(param(name))}</textarea>""") | ||
} | ||
|
||
/** | ||
* Render a checkbox. | ||
*/ | ||
def checkbox(name: String, value: String, attributes: (String, String)*): Unit = { | ||
val checked = if (params(name).contains(value)) "checked" else "" | ||
unescape(s"""<input type="checkbox" name="${escape(name)}" value="${escape(value)}" $checked ${attrs(attributes: _*)}>""") | ||
} | ||
|
||
/** | ||
* Render a radio button. | ||
*/ | ||
def radio(name: String, value: String, attributes: (String, String)*): Unit = { | ||
val checked = if (param(name) == value) "checked" else "" | ||
unescape(s"""<input type="radio" name="${escape(name)}" value="${escape(value)}" $checked ${attrs(attributes: _*)}>""") | ||
} | ||
|
||
/** | ||
* Render a select box. | ||
*/ | ||
def select(name: String, values: Seq[(String, String)], multiple: Boolean, attributes: (String, String)*): Unit = { | ||
val sb = new StringBuilder() | ||
sb.append(s"""<select name="${escape(name)}" ${if (multiple) "multiple" else ""}>""") | ||
values.foreach { | ||
case (value, label) => | ||
val selected = if (params(name).contains(value)) "selected" else "" | ||
sb.append(s"""<option value="${escape(value)}" $selected>${escape(label)}</option>""") | ||
} | ||
sb.append("</select>") | ||
unescape(sb.toString) | ||
} | ||
|
||
/** | ||
* Retrieve an error message of the specified field. | ||
*/ | ||
def error(name: String): Option[String] = { | ||
Option(request.getAttribute(RequestAttributeErrorsKey)).flatMap { errors => | ||
errors.asInstanceOf[Seq[(String, String)]].find(_._1 == name).map(_._2) | ||
} | ||
} | ||
|
||
/** | ||
* Retrieve all error messages of the specified field. | ||
*/ | ||
def errors(name: String): Seq[String] = { | ||
Option(request.getAttribute(RequestAttributeErrorsKey)).map { errors => | ||
errors.asInstanceOf[Seq[(String, String)]].collect { case error if error._1 == name => error._2 } | ||
}.getOrElse(Nil) | ||
} | ||
|
||
private def escape(value: String): String = { | ||
value.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """) | ||
} | ||
|
||
private def params(name: String): Seq[String] = { | ||
Option(request.getAttribute(RequestAttributeParamsKey)).flatMap { params => | ||
params.asInstanceOf[MultiParams].get(name) | ||
}.getOrElse(Nil) | ||
} | ||
|
||
private def param(name: String): String = { | ||
params(name).headOption.getOrElse("") | ||
} | ||
|
||
private def attrs(attrs: (String, String)*): String = { | ||
attrs.map { case (name, value) => s"""${escape(name)}="${escape(value)}"""" }.mkString(" ") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters