scala - How do I require booleans in Play forms? -


i'm using play 2.1.0. i'm trying create action accepts post request , requires boolean required in request body. what's happening if don't supply param action gets false value. test code:

// /post/boolean/single routes method def posttestbooleansingle = action { implicit request =>     val form = form("flag" -> boolean)     form.bindfromrequest.fold(         formwitherrors =>             badrequest(formwitherrors.errors map (fe => fe.key + ": " + fe.message) mkstring ", "),         flag => ok(f"got $flag%b")     ) }  // /post/num/single routes method def posttestnumsingle = action { implicit request =>     val form = form("num" -> number)     form.bindfromrequest.fold(         formwitherrors =>              badrequest(formwitherrors.errors map (fe => fe.key + ": " + fe.message) mkstring ", "),         num => ok(f"got $num%d")     ) }  $ curl -xpost -d "num=42" http://localhost:9000/post/num/single got 42 $ curl -xpost http://localhost:9000/post/num/single num: error.required // didn't provide num error $ curl -xpost -d "flag=true" http://localhost:9000/post/boolean/single got true $ curl -xpost http://localhost:9000/post/boolean/single got false // ??? 

how require boolean parameter?

i'm not sure why, form mapping boolean type appears default false in absence of parameters.

here's snippet responsible format.scala in play source:

/**  * default formatter `boolean` type.  */ implicit def booleanformat: formatter[boolean] = new formatter[boolean] {    override val format = some(("format.boolean", nil))    def bind(key: string, data: map[string, string]) = {     right(data.get(key).getorelse("false")).right.flatmap {       case "true" => right(true)       case "false" => right(false)       case _ => left(seq(formerror(key, "error.boolean", nil)))     }   }    def unbind(key: string, value: boolean) = map(key -> value.tostring) } 

the important part here data.get(key).getorelse("false"). in absence of input, defaults booleans false. you'll want create custom formatter , use define custom binding booleans.

i'll leave put these in places in code base, pieces of puzzle should this:

// custom formatter support custom mapping. import play.api.data.format.formatter implicit def requiredbooleanformatter: formatter[boolean] = new formatter[boolean] {    override val format = some(("format.boolean", nil))    def bind(key: string, data: map[string, string]) = {     right(data.get(key).getorelse("")).right.flatmap {       case "true" => right(true)       case "false" => right(false)       case _ => left(seq(formerror(key, "error.boolean", nil)))     }   }    def unbind(key: string, value: boolean) = map(key -> value.tostring) }  // custom mapping used in form import play.api.data.forms val requiredboolean: mapping[boolean] = forms.of[boolean](requiredbooleanformatter) 

notice change .getorelse("false") .getorelse(""). code same, we're pushing empty values error catcher instead of making them take false value. (note: explicitly specify requiredbooleanformatter in example clarity, since requiredbooleanformatter implicit , in scope, don't have to.)

now can use requiredboolean instead of boolean in forms require param explicitly set in request.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -