A library to validate and map request parameters for Scalatra.
Notice: This project is maintained no longer because it has been merged into Scalatra! See the Scalatra documentation to know details.
At first, add the following dependency into your build.sbt to use scalatra-forms.
libraryDependencies += "io.github.gitbucket" %% "scalatra-forms" % "1.1.0"
Next, add ValidationJavaScriptProvider
to Bootstrap of your Scalatra application.
import io.github.gitbucket.scalatra.forms._
class ScalatraBootstrap extends LifeCycle {
override def init(context: ServletContext) {
...
context.mount(new ValidationJavaScriptProvider, "/assets/js/*")
...
}
}
scalatra-forms is now ready.
Define a form mapping. It's a similar to Play2, but scalatra-forms is more flexible.
import io.github.gitbucket.scalatra.forms._
case class RegisterForm(name: String, description: String)
val form = mapping(
"name" -> text(required, maxlength(40)),
"description" -> text()
)(RegisterForm.apply)
Next, create a servlet (or filter) which extends ScalatraServlet (or ScalatraFilter).
It also mixed in FormSupport
or ClientSideValidationFormSupport
.
The object which is mapped request parameters is passed as an argument of action.
class RegisterServlet extends ScalatraServlet with ClientSideValidationFormSupport {
post("/register", form) { form: RegisterForm =>
...
}
}
In the HTML, you have to do two things below.
- Add
<script>
to import jQuery which is required by validation.js - Add
<script>
to import validation.js which helps client side validation provided byValidationJavaScriptProvider
- Add
validation="true"
to your<form>
scalatra-forms registers a submit event listener to validate form contents.
This listener posts all the form contents to FORM_ACTION/validate
.
This action is registered by scalatra-forms automatically to validate form contents.
It returns validation results as JSON.
In the client side, scalatra-forms puts error messages into span#error-FIELD_NAME
.
<script src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script src="/assets/js/validation.js"></script>
...
<form method="POST" action="/register" validation="true">
Name: <input type="name" type="text">
<span class="error" id="error-name"></span>
<br/>
Description: <input type="description" type="text">
<span class="error" id="error-description"></span>
<br/>
<input type="submit" value="Register"/>
</form>
You can create custom Constraint
.
def identifier: Constraint = new Constraint(){
override def validate(name: String, value: String): Option[String] =
if(!value.matches("^[a-zA-Z0-9\\-_]+$")){
Some(s"${name} contains invalid character.")
} else {
None
}
}
val form = mapping(
"name" -> text(required, identifier),
"description" -> text()
)(RegisterForm.apply)
You can also create multi field validator by overriding validate(String, String, Map[String, String])
.
It's possible to look up other field value via params
.
Other way to create multi field validator is calling verifying
for mapping.
You can give the function yo validate the mapped case class. This function takes the mapped value and returns
Seq[(String, String)]
which contains errors or Nil
.
val form = mapping(
"reason" -> number(required),
"description" -> optional(text)
)(ReasonForm.apply).verifying { value =>
if(value.reason == 4 && value.descripsion){
Seq("description" -> "If reason is 'Other' then description is required.")
} else {
Nil
}
}
For the Ajax action, use ajaxGet
or ajaxPost
instead of get
or post
.
Actions which defined by ajaxGet
or ajaxPost
return validation result as JSON response.
class RegisterServlet extends ScalatraServlet with ClientSideValidationFormSupport {
ajaxPost("/register", form) { form: RegisterForm =>
...
}
}
In the client side, you can render error messages using displayErrors()
.
$('#register').click(function(e){
$.ajax($(this).attr('action'), {
type: 'POST',
data: {
name : $('#name').val(),
description: $('#description').val()
}
})
.done(function(data){
$('#result').text('Registered!');
})
.fail(function(data, status){
displayErrors($.parseJSON(data.responseText));
});
});
- Scalatra 2.5.0 and Scala 2.12 support
- Move to GitBucket organization.
- Change group id and package name to
io.github.gitbucket
. - Add
put()
,delete()
,ajaxPut()
andajaxDelete()
toClientSidevalidationFormSupport
.
- Fix performance issue
- Support Scala 2.11 and Scalatra 2.3
- Bug fix about form state after after validation succeeded.
- Bug fix for
long
value type.
- Formatting (such as
%s
) is available in custom messages as same as default messages.
- Fix
dummy()
bug.
- Add
long
value type. - Fix
list
bug for un-nested properties.
- Add
dummy
value type.
- Fix nested property handling problem.
- Fix
verifying()
forMappingValueType
and removeMappingConstraint
instead of it. - Add
length
constraint.
- Add
MappingConstraint
to validate converted object byMappingValueType
.
- Add
list()
mapping forSingleValueType
. ValidationJavaScriptProvider
adds Content-Type header for validation.js.- Fix to run parent validations before number checking.
- Add
oneOf()
constraint which checks whether the value is one of specified strings. - Fix to retrieve error message for
number()
anddouble()
from ResourceBundle.
- Add
double()
anddate()
mapping. - Add I18N support for error messages.
- Add
ValidationJavaScriptProvoider
. - Add
list()
mapping for List property.
- Improved nested property support.
- Add
validate(String, String, Map[String, String])
toConstraint
. It makes possible to access other parameter in single field validation. - Add
verify()
toMappingValueType
which validates the mapped instance.
- This is the first public release.