title: Play: Bind a form field to a double?
body: <p>Perhaps I'm just overlooking something obvious but I can't figure out how to bind a form field to a double in a Play controller.</p>
  
  <p>For instance, assume this is my model:</p>
  
  <pre><code>case class SavingsGoal(
  timeframeInMonths: Option[Int],
  amount: Double,
  name: String
  )
  </code></pre>
  
  <p>(Ignore that I'm using a double for money, I know that's a bad idea, this is just a simplified example)</p>
  
  <p>And I wanted to bind it like so:</p>
  
  <pre><code>object SavingsGoals extends Controller {
  
      val savingsForm: Form[SavingsGoal] = Form(
  
          mapping(
              "timeframeInMonths" -&gt; optional(number.verifying(min(0))),
              "amount" -&gt; of[Double],
              "name" -&gt; nonEmptyText
          )(SavingsGoal.apply)(SavingsGoal.unapply)
  
      )
  
  }
  </code></pre>
  
  <p>I realized that the <code>number</code> helper only works for ints but I thought using <code>of[]</code> might allow me to bind a double.  However, I get a compiler error on this: </p>
  
  <pre><code>Cannot find Formatter type class for Double. Perhaps you will need to import
  play.api.data.format.Formats._  
  </code></pre>
  
  <p>Doing so doesn't help as there's no double formatter defined in the API.</p>
  
  <p>This is all just a long way of asking what's the canonical way of binding a form field to a double in Play?</p>
  
  <p>Thanks!</p>
  
  <p>edit: 4e6 pointed me in the right direction.  Here's what I did using his help:</p>
  
  <p>Using the snippets in his link, I added the following to app.controllers.Global.scala:</p>
  
  <pre><code>object Global {
  
      /**
       * Default formatter for the `Double` type.
       */
      implicit def doubleFormat: Formatter[Double] = new Formatter[Double] {
  
        override val format = Some("format.real", Nil)
  
        def bind(key: String, data: Map[String, String]) =
          parsing(_.toDouble, "error.real", Nil)(key, data)
  
        def unbind(key: String, value: Double) = Map(key -&gt; value.toString)
      }
  
      /**
       * Helper for formatters binders
       * @param parse Function parsing a String value into a T value, throwing an exception in case of failure
       * @param error Error to set in case of parsing failure
       * @param key Key name of the field to parse
       * @param data Field data
       */
      private def parsing[T](parse: String =&gt; T, errMsg: String, errArgs: Seq[Any])(key: String, data: Map[String, String]): Either[Seq[FormError], T] = {
        stringFormat.bind(key, data).right.flatMap { s =&gt;
          util.control.Exception.allCatch[T]
            .either(parse(s))
            .left.map(e =&gt; Seq(FormError(key, errMsg, errArgs)))
        }
      }
  
  }
  </code></pre>
  
  <p>Then, in my form mapping:</p>
  
  <pre><code>mapping(
      "amount" -&gt; of(Global.doubleFormat)
  )
  </code></pre>