score:0

Accepted answer

Ok. The problem was in the old implementation of QueryBinders that were missing the JavaScript part. The proper version is:

package models

import play.api.mvc.{JavascriptLitteral, QueryStringBindable}


//TODO: remove when updating to 2.1                                                                                                                                                                                

object QueryBinders {

  /**                                                                                                                                                                                                              
   * QueryString binder for List                                                                                                                                                                                   
   */
  implicit def bindableList[T: QueryStringBindable] = new QueryStringBindable[List[T]] {
    def bind(key: String, params: Map[String, Seq[String]]) = Some(Right(bindList[T](key, params)))
    def unbind(key: String, values: List[T]) = unbindList(key, values)

    /////////////// The missing part here...:
    override def javascriptUnbind = javascriptUnbindList(implicitly[QueryStringBindable[T]].javascriptUnbind)
  }

  private def bindList[T: QueryStringBindable](key: String, params: Map[String, Seq[String]]): List[T] = {
    for {
      values <- params.get(key).toList
      rawValue <- values
      bound <- implicitly[QueryStringBindable[T]].bind(key, Map(key -> Seq(rawValue)))
      value <- bound.right.toOption
    } yield value
  }

  private def unbindList[T: QueryStringBindable](key: String, values: Iterable[T]): String = {
    (for (value <- values) yield {
      implicitly[QueryStringBindable[T]].unbind(key, value)
    }).mkString("&")
  }

  /////////// ...and here
  private def javascriptUnbindList(jsUnbindT: String) = "function(k,vs){var l=vs&&vs.length,r=[],i=0;for(;i<l;i++){r[i]=(" + jsUnbindT + ")(k,vs[i])}return r.join('&')}"

  /**                                                                                                                                                                                                              
   * Convert a Scala List[T] to Javascript array                                                                                                                                                                   
   */
  implicit def litteralOption[T](implicit jsl: JavascriptLitteral[T]) = new JavascriptLitteral[List[T]] {
    def to(value: List[T]) = "[" + value.map { v => jsl.to(v)+"," } +"]"
  }

}

Now the query looks like this:

PUT /admin/users?user=506b5d70e4b00eb6adcb26a7&user=506b6271e4b00eb6adcb26a8

And finally everything works.

Final note:

In the Play! framework 2.1+ it should work without adding the code in the project sources. Actually the code is borrowed as-is from Play20/framework/src/play/src/main/scala/play/api/mvc/Binders.scala


Related Query

More Query from same tag