I am getting null values for the search parameters in my controller while clicking Forward button of Pagination in my GSP page - grails

I am using < g:paginate > tag for pagination functionality in my GSP page as given below:
<g:paginate next="Forward" prev="Back" maxsteps="0" max="${max}"
offset ="${offset}" controller="job" action="getEmployee"
total="${employeeCount}"/>
Here value of offset, max and employeeCount is acquired from controller. In my GSP page, I have search fields like Name, Age etc in my form. When I click search button with some value Name or Age, I get data with multiple page displayed in my screen. When I click "Forward" button, the value for the search parameter (Name, Age) is null when I debugged and saw in jobController. So, I am getting exception.How can I pass my search parameters to the controller on clicking Forward button so that I can add these values in search criteria? Please help me with this condition. Currently I am accessing the parameters in controller by using code:
def name = params.name // this gives me null value
def age = params.age // this gives me null value

First, take a look at the documentation for the pagination tag.
You'll notice that there is this:
params (optional) - A Map of request parameters
Now, if you simply want to include the parameters that were used when the GSP was rendered you could try adding the params attribute like this:
<g:paginate params="${params}" next="Forward" prev="Back" maxsteps="0" max="${max}"
offset ="${offset}" controller="job" action="getEmployee"
total="${employeeCount}"/>
Of course, this all depends on your requirements which you didn't make very clear.

Related

How to call a field in my controller

I have a comments model, and within that model, I have a field called :honey.
In the view, :honey is a hidden form field.
In the controller, when the form posts I want it to redirect to the home page if :honey is filled out.
How do I call that specific field in my controller?
If you're talking about when your form posts back to your action, you should be checking params. Either look in your logs or use binding.pry and look for the key and value you're expecting.
It will probably be params[:comment][:honey].

Grails g:paginate - Passing search parameters back to Controller

I have built an advanced search option that allows users to search a multitude of different fields - 38 possible fields in total.
Once the initial search has been submitted, 10 results are displayed with pagination options at the bottom (using grails' <g:paginate> tag).
I think I have a few problems here.
1) I need to somehow pass the fields back to the controller using the params attribute of the g:paginate tag, but I don't really want to create a params map of 40 something parameters.
2) I pass back to the page from the Controller a map of search parameters (so that they can have a dismissable list of parameters that perform the search again without the dismissed parameter). I can pass this back in the params attribute, but it's passed back to the controller as a String and not a map so I don't know how to iterate through it (I realised this after it iterated through each separate character!).
3) The URL of the links that the g:paginate tag creates could potentially be massive, depending on how much of the search fields the user enters. Could there be a danger of the URL exceeding it's maximum amount?
I'm contemplating changing from the built in grails paginate functionality, and creating a form which I can POST. I'm not sure if this is the best way though, and I may be missing some alternative way to do this that is much better.
Any help greatly received!
You can pass all your parameters to action using pageScope.variables like
<g:paginate params="${pageScope.variables}" total=.../>
index.gsp
<div class="pagination">
<g:paginate total="${personCount ?:0}" max="5" params="${params}" />
</div>
Controller.groovy
def index(Integer max)
{
def c=Person.createCriteria()
def results
int count
params.max = Math.min(max ?: 5, 100)
if(params.name != null)
{
params.max = 4
if(!params.offset)
{
params.offset = 0;
}
count = Person.countByNameLike("%"+params.name+"%")
results=c.list{
like("name","%"+params.name+"%")
maxResults(params.max)
firstResult(params.getInt("offset"))
}
}
else
{
results = Person.list(params)
count = Person.count()
}
respond results, model:[personCount: count]
}
I'd put your search params into session. Thus you can use the very basic grails g.paginate tag w/o polluting it. Each time the user changes his search, the parameters should get updated.
1 and 2) The best solution I found:
for the action:
def list() {
... //use params to filter you query and drop results to resultList of type PagedResultList
return [resultList: resultList, resultTotal: resultList.getTotalCount(), filterParams: params]
}
for the view:
<g:paginate total="${resultTotal}" action="list" params="${filterParams}"/>
See a complete example.
3) The url (and get parameters) limit size is 2000 (see why). If that is a problem to you, you'd better switch to an ajax solution or minimize the url size filtering only the filled params. You could accomplish that replacing this line:
return [resultList: resultList, resultTotal: resultList.getTotalCount(), filterParams: params.findAll{ it.value } ]

Grails - remoteField with additional parameters (3 parameters, no id work around)

In a work around I've used in the past, I've used the id field to pass an additional parameter that I needed. But I need to pass three parameters through a remoteField and now am presented with the fact I need to find a way to pass these parameters:
<g:remoteField action="updateFields" update="theDiv" id-"${personInstance.id}" paramName="search" name="updateFields" value="" />
Need: The search field (search), the person id (id), and now I need the company the person works for (c_id).
I can do something like this:
<g:remoteField action="updateFields" update="theDiv" id-"${personInstance.id}" paramName="search" name="updateFields" value="" params="${[c_id:c_id, search:/'+this.value+/']}"/>
If I try to obtain the search value with the params, the search field is now '+this.value+'. Can I just pass the object search field as an addition param in the map (like above) by referencing this.value? If so, what am I doing wrong, since my gsp doesn't load.
Edit
My current work around is to tie both IDs in a ID field, split by a delimiter and then broken into an array once it reaches the controller (obviously not ideal!)
Although I don't use remoteField, I do use remoteFunction frequently and have found I can use multiple javascript based variables directly with the 'params' parameter. E.g.
<script>
function someJSFunction(id1,id2,id3) {
<g:remoteFunction action="ajax_function" params="{id1:id1,id2:id2,id3:id3}" update="someDiv"/>
}
</script>
Hope that helps.

request variables in grails

EDIT: based on feedback, erased original Q. completely and reposting in better language
I wish to access a request or params variable and pass it between the controller and the gsp. i understand that the params object contains everything that a querystring has.
All the examples I see are all Model driven.
I have looked up docs online and I have two books - beginning-grails and definitive guide to grails, both have database driven examples on params. I want to understand how params can be set and accessed. All I read everywhere is that it is a map of request variables.
My scenario is as follows:
I have a controller which sends a list (not from a database) to the GSP. I thought of passing a "params" variable between GSP and the controller.
To reiterate, the scenario I have is not a Model driven one. I am looking to iterate thru a list of items (with no database count known) and is driven by user click. I thought of implementing something like what twitter has "the-more-button-on-the-bottom". have a simple remotelink at the bottom of the page with a new page counter, which i access in the controller and pass to my service class for the new part of list.
controller code:
//access params from request
int pageInt =params["pagecount"] // *i always get null here*
callMyList(pagecount) //calls my service method to get next set of list for next page
GSP (not actual) code
<%= params.get("pagecount") %>
<%= nxtPage = pagecount++ %>
...
<%params["myId"] = nxtPage%>
<g:remoteLink action="list" id="${nxtPage}">More</g:remoteLink>
The params object is only useful for getting values from the query string of the current request. Setting a value in params in a GSP won't do anything. Params is a request scope object, with each new request it is an entirely new object. To pass a value from your GSP to your List controller, that value must be in the query string of the new request to the controller. In your case, it looks like you want to put it in your "More" link. The way your remoteLink tag is written, the value of nxtPage should be in params.id in your List controller, so you could access it that way. If you want to be in params.pagecount you would have to put it in the params attribute of you remoteLink tag. Something like this:
<g:remoteLink action="list" params="[pagecount: nxtPage]">More</g:remoteLink>
def urlString = request.scheme + "://" + request.serverName + ":"
+ request.serverPort + "/" + grailsApplication.metadata.'app.name'
+ "/" + controllerName + "/"

How to get the selected value of a dropdown in the MVC View itself

I have a drop down in a MVC View, which is some thing like this:
Html.DropDownList(id, Range(0,10)
.Select(x => new SelectListItem {Text = x, Value = x}))
In the view itself, I need the selected value of this drop down. I know that I can access that in a JavaScript, but I am looking for a way to get it in the view itself from the drop down properties or something like that.
How can I access it? I tried to figure out some thing from intellisense but nothing relavant showed up, help is much appreciated.
Edit: I want the value after a few lines after the declaration of the drop down, I know that I can access it from JavaScript and by posting the form, Is there noway to access it on the view itself ?
Edit2: If its not possible to access it in view, please explain the reason, I am more interested in knowing it.
Thanks.
After reading at your question, it sounds like you want to have the drop down list supply a value for a lower section of the same page.
First and foremost, you will need to place the DropDownList within a form construct, as in:
<% using (Html.BeginForm("ProcessValue", "ThisPage")) { %>
<%= Html.DropDownList("DropID", Range(0, 10).Select(a=>new SelectListItem { Text = x, Value = x }) %>
<input type=submit value="Submit" />
<% } %>
You need to set up a few things ahead of time:
You have to have a submit button, or a similar construct, in order to retrieve the value of the DropID variable.
You need to set up an controller method that will handle the processing of the value, then redirect back to the original page with the selected value in the page's ViewData.
Finally, you need to set up the view so that the post-processing section will only display if you have a valid value in the DropID variable.
It's not as simple as just placing a DropDownList in a view and then using that value later on in the page. You have to get the controller involved to manage the data transport and you have to set up the single view to handle multiple states (ie. before the value is selected and after the selection takes place).
To get the selected value you could use either javascript or a controller action to which the form containing the select box is submitted.
The selected value will be in the FormCollection or QueryString collection with the name of the DropDown's ID in the controller action that receives the form submission from this view. You can either submit the values with a classic POST or GET or via AJAX, but you have to wire up a server-side action that processes that input.
There is a SelectList class as well wich allows you to define wich item will be selected.. and knowing that - you will know selected value..
Also.. if no value is selected explicitly, dropdowns tend to select the first item in the list.

Resources