2012-10-06 24 views
10

Tal vez estoy pasando por alto algo obvio, pero no puedo entender cómo vincular un campo de formulario a un doble en un controlador de Play.Reproducir: ¿enlazar un campo de formulario a un doble?

Por ejemplo, supongamos que esta es mi modelo:

case class SavingsGoal(
timeframeInMonths: Option[Int], 
amount: Double, 
name: String 
) 

(ignorar que estoy usando un doble por dinero, sé que es una mala idea, esto es sólo un ejemplo simplificado)

y quería obligar a éste, así:

object SavingsGoals extends Controller { 

    val savingsForm: Form[SavingsGoal] = Form(

     mapping(
      "timeframeInMonths" -> optional(number.verifying(min(0))), 
      "amount" -> of[Double], 
      "name" -> nonEmptyText 
     )(SavingsGoal.apply)(SavingsGoal.unapply) 

    ) 

} 

me di cuenta de que el ayudante number sólo funciona para los enteros pero pensé usando of[] podría permitir para vendar una doble. Sin embargo, me sale un error de compilación en esto:

Cannot find Formatter type class for Double. Perhaps you will need to import 
play.api.data.format.Formats._ 

Si lo hace, no ayuda ya que no hay doble formateador definido en la API.

Esto es solo una forma larga de preguntar ¿cuál es la forma canónica de enlazar un campo de formulario a un doble en Play?

Gracias!

editar: 4e6 me indicó la dirección correcta. Esto es lo que hice usando su ayuda:

Utilizando los fragmentos en su enlace, he añadido lo siguiente a app.controllers.Global.scala:

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 -> 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 => T, errMsg: String, errArgs: Seq[Any])(key: String, data: Map[String, String]): Either[Seq[FormError], T] = { 
     stringFormat.bind(key, data).right.flatMap { s => 
     util.control.Exception.allCatch[T] 
      .either(parse(s)) 
      .left.map(e => Seq(FormError(key, errMsg, errArgs))) 
     } 
    } 

} 

Entonces, en mi forma de mapeo:

mapping(
    "amount" -> of(Global.doubleFormat) 
) 

Respuesta

10

En realidad, there is formateador predefinido para Double en la rama principal. Por lo tanto, debe cambiar a la versión de reproducción 2.1-SNAPSHOT o simplemente copiar la implementación.

+0

Gracias! Eso funciona perfectamente. Actualizaré mi pregunta original con mi solución en caso de que alguien más tropiece con esto. – Ryan

+0

Al escribir esto, el enlace a 'doubleFormat' está aquí https://github.com/playframework/playframework/blob/b7c414ef11a1a8befa0caa8dbc52fa4e11128a08/framework/src/play/src/main/scala/play/api/data/format/ Format.scala # L132 (Consejo profesional: presione "y" en github para obtener un enlace permanente vinculado a una confirmación en particular. Como "maestro" se mueve con el tiempo, los enlaces basados ​​en el maestro se pudren con el tiempo). –

11

No necesita utilizar el formato en el global si tiene la versión 2.1 activada.

Sólo importa:

import play.api.data.format.Formats._ 

y utilizar como:

mapping(
    "amount" -> of(doubleFormat) 
) 
Cuestiones relacionadas