Play Framework Form Mappings to JSON
package controllers.utils | |
import play.api.data.validation.Constraint | |
import play.api.libs.json._ | |
import play.api.data._ | |
import play.api.data.Forms._ | |
/** | |
* @author Herman Banken | |
* @since 11/11/16. | |
*/ | |
object FormUtils { | |
def anyFormat(in: Any): JsValue = in match { | |
case i: Int => JsNumber(i) | |
case i: Long => JsNumber(i) | |
case i: BigDecimal => JsNumber(i) | |
case s: String => JsString(s) | |
case s => JsString(s.toString) | |
} | |
implicit val constraintFormat: Writes[Constraint[Any]] = Writes { | |
case constraint => Json.obj( | |
"name" -> constraint.name, | |
"args" -> constraint.args.map(anyFormat) | |
) | |
} | |
implicit val mappingFormat: Writes[Mapping[Any]] = Writes.apply(mapping => Json.obj( | |
"key" -> mapping.key, | |
"constraints" -> Json.toJson(mapping.constraints.toList), | |
"format" -> mapping.format.map(f => Json.arr(JsString(f._1), JsArray(f._2.map(anyFormat)))), | |
"mappings" -> JsArray(mapping.mappings | |
// Mappings seem to be recursive, at least sometimes. Prevent loop: | |
.filter(_ != mapping) | |
.map(_.asInstanceOf[Mapping[Any]]) | |
.map(Json.toJson(_)(mappingFormat))) | |
)) | |
} | |
object Example { | |
import FormUtils._ | |
case class Address(street: String, city: String) | |
case class UserData(name: String, age: Int, address: Address) | |
val addressForm = Form( | |
mapping( | |
"street" -> text, | |
"city" -> text(10) | |
)(Address.apply)(Address.unapply) | |
) | |
val userForm = Form( | |
mapping( | |
"name" -> text, | |
"age" -> number, | |
"address" -> addressForm.mapping | |
)(UserData.apply)(UserData.unapply) | |
) | |
def jsConstaints = Json.toJson(userForm.mapping.asInstanceOf[Mapping[Any]])(mappingFormat) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment