How to bind an enum to a playframework form?

Viewed 1186

I have an enum of the form:

object MatchFilterType extends Enumeration {
  type MatchFilterType = Value
  val gt = Value("gt")
  val lt = Value("lt")
  val eq = Value("eq")
}

Trying to create a form val in my controller:

 case class SearchRequest(mft: MatchFilterType, queryText: String, locations: List[String])

 val searchForm: Form[SearchRequest] = Form(
    mapping(
      "mft" -> ????????,
      "queryText" -> nonEmptyText,
      "locations" -> list(text)
    )(SearchRequest.apply)(SearchRequest.unapply)
  )

I am using play 2.6.x for this project.

How do I map my enumeration in my Form val?

2 Answers

A more generic approach:

def enumerationFormatter[E <: Enumeration](enum: E): Formatter[E#Value] = new Formatter[E#Value] {
  override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], E#Value] =
    data.get(key).map(s => enum.withName(s)).toRight(Seq(FormError(key, "error.required", Nil)))
  override def unbind(key: String, value: E#Value): Map[String, String] = Map(key -> value.toString)
}

Which can then be used like:

object TestValues extends Enumeration {
  type TestValue = Value
  val Test: TestValue = Value
}
case class MyForm(testValue: TestValue)
object MyForm {
  implicit val testValueFormatter: Formatter[TestValue] = enumerationFormatter(TestValues)
  val form = Form(mapping("testValue" -> of[TestValue])(MyForm.apply)(MyForm.unapply))
}
Related