Damian
Damian

Reputation: 1553

How can I handle decimal numbers using the Scala framework play

I want to be able to enter decimal numbers into a play form. I would like to have the following mapping, but it does not compile.

mapping(
 "id" -> ignored(NotAssigned:Pk[Long]),
 "date" -> date("yyyy-MM-dd"),
 "amount" -> decimal,
 "description" -> nonEmptyText
)(Expense.apply)(Expense.unapply)

There must be a way. I am very new to Scala and Play. Any pointers, greatly appreciated.

Upvotes: 2

Views: 2997

Answers (3)

flurdy
flurdy

Reputation: 3972

As of this pull request you can now specify BigDecimal as a type of input. Modifying the OP's Example:

mapping(
 "id" -> ignored(NotAssigned:Pk[Long]),
 "date" -> date("yyyy-MM-dd"),
 "amount" -> bigDecimal,
 "description" -> nonEmptyText
)(Expense.apply)(Expense.unapply)

Note the bigDecimal mapping type.

For further precision and scale you can specify them as:

 "amount" -> bigDecimal(10, 2)

Upvotes: 3

Stephen Harrison
Stephen Harrison

Reputation: 699

Here's the actual code for the implicit you need. I put them in a separate object because I have a lot of these for my own types too. It's very handy to be able to use custom types in Forms this way.

object FormFieldImplicits {
  // Code merged into future Play release
  //
  implicit def doubleFormat = new Formatter[Double] {
    def bind(key: String, data: Map[String, String]) = Right(data(key).toDouble)
    def unbind(key: String, value: Double) = Map(key -> value.toString)
  }

  ...
}

Then just import FormFieldImplicits._ in your controller where you want to use a mapping of[Double] and Bob's your uncle as follows

def impactMapping = mapping(
    "value" -> of[Double],
    "percent" -> of[Double])(Impact.apply)(Impact.unapply)

Upvotes: 2

4e6
4e6

Reputation: 10776

There is method of[T] on object Forms, that creates mapping of type T. In your case it would be of[Int]:

mapping(
 "id" -> ignored(NotAssigned:Pk[Long]),
 "date" -> date("yyyy-MM-dd"),
 "amount" -> of[Int],
 "description" -> nonEmptyText
)(Expense.apply)(Expense.unapply)

There are also two helper methods

val number: Mapping[Int] = of[Int]
val longNumber: Mapping[Long] = of[Long]

which are just reference generic of function.

Upvotes: 4

Related Questions