I have a Groovy application. I am rendering the view list using the following statement:
render (view: 'list', model:[reportingInstanceList: reportingInstanceList, reportingInstanceTotal: i, params: params])
The list.gsp is as follows:
The view is rendered but the default sorting is not working.
<g:sortableColumn class="tabtitle" property="id" title="Id" titleKey="reporting.id" />
<g:sortableColumn class="tabtitle" property="company" title="Company" titleKey="reporting.company" />
Unfortunately the default sorting (by id, by company, etc) are not working.
Any hint why?
Thanks a lot in advance.
Luis
If you are asking about the sorting/order links at the top of the columns on the list page, the links are hrefs back to the controller and method that was originally used to populate the list. Plus the URLs include parameters for sort and order. For instance:
/tracker/bug/searchCurrentUserProject?sort=name&order=asc
The controller method will then need to handle the sort and order values from the link:
params.sort = params.sort ?: "priority"
params.order = params.order ?: "asc"
And pass them to the database query:
def bugList = Bug.createCriteria().list(
sort:params.sort,
order:params.order,
max:params.max,
offset:params.offset) {
eq "projectId", new Integer (params.projectId)
}
You can add two hidden fields in your form, set them dynamically with Javascript and send them together with your form.
Related
I have two entities: Event and Person.
I have both gsp pages that allows me to create events and persons. In Event page, I have the possibility to select an existing person, or I can insert name, surname and phone number.
I would have a button that, if that three fields are filled, allows me to jump to create page of Person, with that three fields filled with data inserted in Event page.
I've tried with tag as follows:
<g:link controller="patient" action="create"
params="[name: eventInstance.patientName, surname: eventInstance.patientSurname,
phone_1: eventInstance.phoneNumber]">link</g:link>
but in this way parameters are empty.
Any suggestion?
EDIT:
I've tried the following:
<g:actionSubmit value="createPatient" action="createPatient"></g:actionSubmit>
and the action is:
def createPatient()
{
def eventInstance = new Event(params)
println("params are "+ params)
redirect(controller: "patient", action: "create", params: [name: "name", surname:
"surname", phone_1: "025-84569"] )
}
In this way, the Create action is performed and I see the gsp page with form prefilled with parameter passed. The fact is that params has not the values that I want to pass to create.gsp (values needed are patientName, patientSurname and phoneNumber). Infact, the println() shows me:
params are [_action_createPatient:createPatient, recurInterval:1, recurCount:,
recurType:DAILY, endTime:, recurEndOption:never, recurUntil:, startTime:, title:,
patient_textField:, healthService.id:1, healthService:[id:1], patientName:,
phoneNumber:, description:, _recurDaysOfWeek:[, , , , , , ], patientSurname:,
patient_id:, action:save, controller:event]
I'm a newbie trying to find uses for Neo4J on Grails.
Basically, I've made 20 grocery item nodes through the Neo4J browser and I want to create a simple Grails site that will let users search a grocery item and visually show the items related to it.
My index.gsp has:
<input id="item" />
My viz.js has:
$('#item').keyup(function() {
var item = $('#item').val();
My Item Domain class has
class Item {
static mapWith = "neo4j"
String name
My ItemController class has:
def index() {
def item = Item.list() [item:item] //No idea, just trying out whatever i find :(
and a query with something like:
def query = Item.cypherStatic ("""start n=node({Item}) match (n)-[r]->(x) where r='partner' return n, x)
Questions:
How can I properly send the JS 'item' variable into the ItemController?
How can I use the 'item' variable to properly query the node names which have a 'partner' relationship with the item?
in addition to Motilals answers, you definetly need a wrapping form with an action that points your controller
like
<g:form controller="itemController" action="index" >
<input type="text" id="item" name="item" value="" />
<input type="submit" value="submit" >
</g:form>
then on clicking submit the for will call your index action and there you could parse the value with
def item = params.item
but it looks more like you want some asynchronous stuff right after keyup-function, therefore you could do sth like this :
$('#item').keyup(function() {
var item = $('#item').val();
$.ajax({
url: "${createLink(controller:'itemController', action:'index')}",
data:"&item="+item
})
.done(function( data ) {
console.log(data)
});
});
in this case, you need to pay attention what your index-action is returning, so you can do in the .done() whatever you want with the response.
also note, that when you name an action "index" it will be available at
.../myproject/item/index
or, and thats important
.../myproject/item/
so if your index method requires the data from the input, it will miss them if a user has gone straight to that url
so your index action would rather render the page with the input
and you define another action for executing your query based on input and returning data
set the item to hidden field and then you can access it directly in your controller using params
here you go:
//in index.gsp add below hidden field and set the hidden filed in your js code
<g:hiddenField name="item" value="" />
$('#item').keyup(function() {
var item = $('#item').val();
//in your controller
def index() {
def item = params.item
print item // you see the value for item
//do your stuff
}
once you have item value you could directly use HQL query or use the domain instance
hope this helps you
Regards
Motilal
I've scoured the web for almost a day and can't seem to find a solution to my problem.
I have a lookup table called Hobby which has a bunch of hobbies in it (camping, hiking, biking, etc). The hobbies table is populated during the bootstrap. Grails creates a hobby table with an id, and description field.
I have a domain object called Applicant. An applicant can have zero or more hobbies. I've declared the domain like this:
class Applicant {
static hasMany = [hobbies:Hobby]
List <Hobby> hobbies = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(Hobby.class));
}
In my controller I'm using a command object for the page that will allow the applicant to select their hobbies. It is defined as:
class LifestyleCommand {
List <Hobby> hobbies = LazyList.decorate(new ArrayList(), FactoryUtils.instantiateFactory(Hobby.class));
}
My gsp looks like this:
<g:each var="item" in="${Hobby.list()}" status="i">
<g:set var="newline" value="${(i % 3) == 0 ? 'newline' : ''}" />
<div class="formcheckbox columns3 ${newline}">
<g:checkBox name="hobbies_${item.id}" optionKey="id" value="${item.id}" />
<label>${item.description}</label>
</div>
</g:each>
The page will display all of the hobbies in the page correctly. However when I try to submit the form back to the controller the list in the LifeStyleCommand object is null. I'm not sure if my gsp has the g:checkBox variables set correctly, and I'm not sure if I declared the List in the command object correctly either. Once I get the data to be sent back to the controller, my next problem to overcome will be copying the data from the command object to the Applicant. Any help would be appreciated.
I've tried using just a plain List in the command but grails complains about type conversions when the form is submitted.
EDIT:
Here is what I got to work:
class Applicant {
static hasMany = [hobbies:Hobby]
//I removed the List <hobby>... code
...
}
My command object:
class LifestyleCommand {
Set <Hobby> hobbies;
}
gsp:
<g:each in="${Hobby.list()}" var="hobby">
<g:set var="checked" value="${ command?.hobbies.find{h->h.id == hobby.id } != null }" />
<g:checkBox value="${checked}" name="${ 'hobby' +'[' + hobby.id + ']'}"/>${hobby.description}</td>
</g:each>
And my new controller code:
Hobby.list().each{hobby->
if (params["hobby[${hobby.id}]"] == 'on') {
applicant.addToHobbies(hobby)
}
else if (applicant.getHobbies().contains(hobby)) {
applicant.removeFromHobbies(hobby)
}
}
Everything is working. There may be better ways, and I haven't done any refactoring yet but having it work is a starting point.
The problem is with your GSP. When you need a list of objects, you have to maintain a standard name for your checkbox:
<g:checkBox name="hobbies[$i].id" ... />
This will be mapped correctly to your command list.
I have 2 domains
Portfolio
static hasMany [publications: Publication]
String portfolioName
Publication
static belongsTo = [portfolio: Portfolio]
String publicationName
String pubcontent
String published
String publisheddate
I am wanting to g:render or tmpl the Publication list view or a new partial view in the show view for the Portfolio domain. This all works fine and displays perfectly if I adjust the publication list view to pass the portfolio params in portfolioInstance?.publications.
Problem:
When I want to sort on the table headings from the publications list view, the sort moves the data around but does not follow any sort order. I have tried all domain tricks, such as List publications, comparators, etc., I have messed around with modifying the view using .sort{a,b-> a.id.compareTo(b.id)} but am still not getting them sorted correctly.
How do I get these columns to sort correctly? To reiterate, I need or want all columns in the table to be sortable.
What I have done so far and not worked:
<g:sortableColumn is in the view
domain class Portfolio used List publications
comparators inline in the view
many other things.
Where am I going wrong? Do I need to write a new method under the portfolio controller to handle a list action and params sort or can I do something in the views to fix this.
example list view - cut down for brevity
<g:each in="${portfolioInstance?.publications }" status="i" var="pubs">
<g:link controller="publication" action="show" id="${publicationInstance.id}">${fieldValue(bean: publicationInstance, field: "publicationName")}</g:link>
<td><g:formatDate date="${pubs.publisheddate}" /></td>
<td>${fieldValue(bean: publicationInstance, field: "published")}</td>
Controllers
Standard grails generated controller
def show(Long id) {
def portfolioInstance = Portfolio.get(id)
portfolioInstance.properties=params
def list(Integer max) {
params.max = Math.min(max ?: 10, 52)
if (params.sort==null){
params.sort = "published"
}
[publicationInstanceList: Publication.list(params), publicationInstanceTotal: Publication.count()]
See section 6.5.2 ("Default Sort Order") of the GORM Documentation. You just need to add
static mapping = {
sort "publicationName"
}
in your Publication class if you want that to be the field that Publications are sorted by.
How do I structure my pages and partial templates so that Ajax will play nice with <paginate> and column sorting?
I currently have a search.gsp page with a remoteField that calls a controller to update a template. This all works fine. However, the column sorting and paging actions cause my search.gsp to be completely replaced by the template view.
From my search.gsp:
<div id="searchBox">
Enter a key or phrase: <g:remoteField name="searchBox"
update="resourceSearchResultPanel" paramName="q"
url="[controller:'resourceEntry',action:'searchForResources']"
/>
</div>
<div id="resourceSearchResultPanel" />
My controller handles the search request like so:
def searchForResources = {
params.max = Math.min(params.max ? params.max.toInteger() : 10, 100)
params.offset = params.offset ? params.offset.toInteger() : 0
log.debug "Handling search post action"
def q = params.q ?: null
log.debug "Search phrase is $q"
def searchResults
if (q) {
searchResults = [
results: ResourceEntry.search(q,[offset: params.offset, max: params.max]),
resultCount: ResourceEntry.countHits(q),
q: q.encodeAsHTML()
]
}
render(template:"resourceSearchResultPanel",model:searchResults)
}
The _resourceSearchResultPanel.gsp is just a table with this <paginate> tag:
<g:paginate action="searchForResources" total="${resultCount}" params='["q":"${q}"]' />
The problem is that when the <paginate> tag calls the controller, the entire page is refreshed with the contents of the _resourceSearchResultPanel.gsp template, while I just want the _resourceSearchResultPanel.gsp itself to be refreshed inside search.gsp.
There's no update attribute like there is in the remoteField tag...
The paginate tag doesn't support generating ajax links so you'll have to write your own verison of the tag that calls remoteLink instead of link.
cheers
Lee
I would suggest to you remote pagination plugins for Grails. This would suffice your requirement. For more details please refer to following site:-
http://www.grails.org/plugin/remote-pagination
Please feel free to revert incase of any concern.