ThomasK
ThomasK

Reputation: 305

multiple optional parameters - how to use route and template

Since I am starting with Play framework (2.1.3) this seems like a simple questions to me but I haven't figured out a solution, yet.

Maybe there is a complete other approach to get it working and that's why I am not finding examples on this.

I want to show a list of values based on three optional filter values.

My Controller accepts three parameters

public static Result index(Integer filterA, String filterB, String filterC)

The route sending the request to it

GET / controllers.Teachers.index(filterA :Integer = null, filterB = null, filterC = null)

this will accepts URLs like localhost:9000/?filterA=10&filterB=20&filterC=test

The filters should be selectable through three list by just clicking on a value, so my link within the template looks like

<a href="@routes.Teachers.index()?filterA=10">Value for filter A</a>
<a href="@routes.Teachers.index()?filterB=20">Value for filter B</a>
<a href="@routes.Teachers.index()?filterC=test">Value for filter C</a>

I think this is not the "play way" to do it since I take play out of the control of generating the URL. Additionally, when I want to set two filters together, I have to pass the selcted filter to my template (parameter or session) and have complex links like this:

<a href="@routes.Teachers.index()?filterA=10&filterB=@selectedB&filterC=@selectedC">Value for filter A</a>
<a href="@routes.Teachers.index()?filterA=@selectedA&filterB=20&filterC=@selectedC">Value for filter B</a>
<a href="@routes.Teachers.index()?filterA=@selectedA&filterB=@selectedB&filterC=test">Value for filter C</a>

So in my opinion, this is a really common usecase but I haven't figured out how to do this easily within play :)

Upvotes: 2

Views: 2046

Answers (1)

ndeverge
ndeverge

Reputation: 21564

You have to call the action by passing arguments to it in your template:

<a href="@routes.Teachers.index(10, null, null)">Value for filter A</a>
<a href="@routes.Teachers.index(null, 20, null)">Value for filter B</a>
<a href="@routes.Teachers.index(null, null, "test")">Value for filter C</a>

So you don't have to put default values in your routes file:

GET / controllers.Teachers.index(filterA :Integer, filterB :Integer, filterC: String)

Or if you want to keep them optional, you can call them if your template with:

<a href="@routes.Teachers.index(filterA = 10)">Value for filter A</a>
<a href="@routes.Teachers.index(filterB = 20)">Value for filter B</a>
<a href="@routes.Teachers.index(filterC = "test")">Value for filter C</a>

with the following route:

GET / controllers.Teachers.index(filterA : Int ?= 0, filterB ?= null, filterC ?= null)

Note, that Java's Integer, should be a Scala's Int in the route file:

public static Result index(Integer filterA, String filterB, String filterC) {
    if (filterA == 0 && filterB == null && filterC == null) {
        return badRequest("No filter data...");
    }
    return ok("some filtering");
}

Upvotes: 4

Related Questions