I am currently working on grails export plugin. The plugin works if I will just do simple list(). But if I associate it with namedquery, it doesn't work anymore. This is part of the code.:
def buildReport(){
if(params?.format && params.format != "html"){
response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
response.setHeader("Content-disposition", "attachment; filename=report.${params.extension}")
exportService.export(params.format, response.outputStream,Building.selectStatus(params.q).list(params), [:], [:])
}
}
The above code doesn't work. It throws this error :
Cannot invoke method getSuperclass() on null object. Stacktrace follows:
Message: Cannot invoke method getSuperclass() on null object
Can anyone help? Thanks.
Update:
I have this in my list.gsp:
<g:form action="list" controller="building">
<g:select id="user" name="q" from="${myapp.Construction.list()}" optionKey="id" required="" value="${constructionId?.id}" class="many-to-one" />
<g:submitButton name="Execute"/>
</g:form>
If I submit that form, it will list or display the the building with the same construction Id. And somewhere down that code is:
<export:formats
formats="['csv', 'excel', 'ods', 'pdf', 'rtf', 'xml']" action="buildReport"/>
That code will call the buildReport. But unfortunatedly the q or params.q of the select is null when calling the buildReport.
By the way, all this code is in one gsp file and it will display the same gsp when submitting the form.
Okay, I think I know why it doesn't works. Its because the params.q of
Building.selectStatus(params.q)
is actually null! I don't know why its null. I have this in my list.gsp to pass the parameter:
<g:textField name="q" value="${params.q ?: ''}" />
So what should be in the gsp to pass the params? Because here, I just found out that it is null.
By the way, before the buildReport is being called, the textfield has a value which the user will input.
Related
In my application, I have search button and based on the search criteria, I have to search data. I have used few hidden variables to store data.
My .gsp page looks like this:
<g:form id="job" name="job" method="POST">
<div>
<input type="hidden" id="country" name="country" value="${country}"/>
<input type="hidden" id="paginationFlag" name="paginationFlag" value="${paginationFlag}"/>
<!-- There are other components like text field, select box etc -->
<g:actionSubmit id="Search" value="Search" formmethod="post" action="findJob"/>
</div>
</g:form>
My respective controller method looks like this:
def findJob(){
def country
def paginationFlag
if(params?.country){
country = params?.country
}else{
country = 'USA'
}
if(params?.paginationFlag){
paginationFlag = params?.paginationFlag
}else{
paginationFlag = 'false'
}
withFormat{
html{
List<Applicant> searchList //get data from database.
// other business logic
render(view : "jobList",model:[paginationFlag: paginationFlag, country:country])
}
json{
// some business logic
def candidateList // value for this candidateList is acquired from database
def json = ['jsn': candidateList]
render json as JSON
}
}
When I click search button and debug the code, first my control goes to controller-> findJob() method and executes the code inside html part.
Secondly, it goes to the gsp page (view page) and sets value.Third, it again goes to the controller and executes the code inside json part.
On the first entry to the controller, the value of paginationFlag and country in param are both null. So it will set the value 'false' and 'USA' respectively. But when control goes to controller again for the second time, again the value of param.paginationFlag and params.country are null. Should not they have the assigned values?
Why is it so? What should I do go get the value of country and paginationFlag in params on the second time? Can any one explain me ? Thank you very much for advance.
The problem is you're using a regular HTML input tag rather than a Grails g:hiddenField tag. Try this:
<g:form id="job" name="job" method="POST">
<div>
<g:hiddenField name="country" value="${country}"/>
<g:hiddenField name="paginationFlag" value="${paginationFlag}"/>
<!-- There are other components like text field, select box etc -->
<g:actionSubmit id="Search" value="Search" formmethod="post" action="findJob"/>
</div>
</g:form>
Tip
You can also simply the params assignment:
def country = params.country ?: 'USA'
def paginationFlag = params.paginationFlag ?: 'false'
I can't tell where the paginationFlag comes from, but know that a boolean is valid.
I'm having difficulties getting my ajaxform working properly. I'm using Grails 2.4.4 and have the following remoteForm code.
view usedProducts
<div id="updateMe">
<g:each in="${productList}" var="product">
${product.item} Success1
</g:each>
</div>
<g:formRemote name="myForm"
url="[controller:'product', action: 'save']" update="updateMe">
<g:textField name="item" required="" value="${newProduct?.item}" />
<g:submitButton name="Save" />
</g:formRemote>
Controller ProductController
def usedProducts = {
[productList:Product.findAll()]
}
#Transactional
def save(Product productInstance) {
productInstance.save flush:true
[productList: Product.findAll()]
}
Console Error
POST http://localhost:8080/TekDays/product/save
404 Not Found
54ms
jquery-...e=false (line 9631)
"NetworkError: 404 Not Found - http://localhost:8080/TekDays/product/save"
I'm afraid you cannot do that this way you're trying to do.
Note that when the AJAX call is effectively being performed by the user there are no more GSP tags. There are only CSS, HTML and Javascript. It's the browser world.
Please put the render in front of what you're returning and test.
#Transactional
def save(Product productInstance) {
productInstance.save flush:true
render Product.findAll()
}
You'll see that the content of the DIV updateMe will be replaced by the content rendered by the save method. The content is a list returned by findAll method with all Product objects.
When you use render the content returned (a GSP template, the content of a variable or a HTML) will be rendered in the current HTML, for instance, through an AJAX call.
For other side when you use the return keyword is expected a GSP with the same name as the controller method. Because of that you're getting a 404, since a save.gsp isn't found. Note: if you omit the return keyword (as you're doing) then the groovyc (Groovy compiler) will implicitly put it for you.
If I understand well what you're trying to do then you must render the content (not return it).
I have been stuck for a couple of days on the same problem and I am not getting anywhere.
I am using a g:formRemote tag to update a messages template
<g:formRemote url="[action: 'updateStatus']" update="messages" name="updateStatusForm"
onSuccess="document.updateStatusForm.message.value='';">
<g:textArea name="message" value="" cols="3" rows="1"/><br/>
<g:submitButton name="Update Status"/>
</g:formRemote>
This form then calls a updateStatus method in my controller
def updateStatus(String message) {
def status = new Post(message: params.message, author: lookupPerson())
status.save(flush: true, failOnError: true)
def messages = currentUserTimeline()
render template: 'profileMessages', collection: messages, var: 'profileMessage'
}
But the def status line should be
def status = new Post(message: params.message, author: lookupPerson(), child: Child.get(childInstance.id)
In my view I have a childInstance which is the selected by the user. Is there anyway I can have a global variable in the controller which is saved or can I send the child instance params id in the formRemote tag. I don't think there is as i've been trying to do it this way all today.
Any help will be good. The only way I know will work will be to write the childInstance.id to a properties file and read it back in but there must be a better way as I think this would be very bad practice.
You can add params to <g:formRemote>
Example from the grails docs:
<g:formRemote name="myForm" update="updateMe"
url="[controller: 'book', action: 'byAuthor', params: [sort: 'title', order: 'desc']]">
Author: <input name="author" type="text" />
</g:formRemote>
You could probably add a <g:hiddenField name="childId" value="${childInstance.id}"/> to your formRemote Tag and this will send it to the server in the same way message is.
I want to select a language with a <g:select> tag and send the selection params to an action when the selection changes. (The param should be visible in the url of the opened view)
I tried different variations of <g:form> and <g:select>:
Version creates the correct params, but doesn't create a rest url:
<g:form name="selectLanguage" <b>action='show' id="${mitarbeiterprofilInstance.id}" lang=lang>
<g:select onchange="submit();"
value="${profilInstance?.sprache?.sprache}"
name="lang"
optionKey="sprache"
optionValue="sprache"
from = "${mitarbeiterprofilInstance.profiles.sprache}" />
</g:form>
Params: [lang:deutsch, id:3, action:show, controller:mitarbeiterprofil]
url: /mitarbeiterprofil/show/3
url should be /mitarbeiterprofil/show/3/deutsch
Version adds the params to the url, but with the wrong action:
<g:form name="selectLanguage" id="${mitarbeiterprofilInstance.id}" lang=lang>
<g:select onchange="submit();"
value="${profilInstance?.sprache?.sprache}"
name="lang"
optionKey="sprache"
optionValue="sprache"
from = "${mitarbeiterprofilInstance.profiles.sprache}" />
</g:form>
Params: [lang:deutsch, id:3, action:index, controller:mitarbeiterprofil]
url: /mitarbeiterprofil/index/3/deutsch
Version chooses the right controller, shows the params in the url, but doesn't use the right parameter:
<g:form name="selectLanguage" id="${mitarbeiterprofilInstance.id}" lang=lang>
<g:select onchange="submit(<b>action='show');"
value="${profilInstance?.sprache?.sprache}"
name="lang"
optionKey="sprache"
optionValue="sprache"
from = "${mitarbeiterprofilInstance.profiles.sprache}" />
</g:form>
params:[lang:show, id:3, action:show, controller:mitarbeiterprofil]
url: /mitarbeiterprofil/show/3/show
Does anyone else have another idea on how I might go about this?
You have to play here with UrlMappings.groovy
Firstly, let's adjust your form:
<g:form name="selectLanguage" action='show' id="${mitarbeiterprofilInstance.id}" >
<g:select onchange="submit();"
value="${profilInstance?.sprache?.sprache}"
name="lang"
optionKey="sprache"
optionValue="sprache"
from = "${mitarbeiterprofilInstance.profiles.sprache}" />
</g:form>
And mapping:
"/mitarbeiterprofil/show/$id/$lang" (controller:"mitarbeiterprofil", action:"show")
This can solve your problem but i'm doubt... So try it and tell us the result :)
P.S. The problem here is in rendering process. Your action url will be created before user selects language. So you have to update url each time user selects language or it will result in url like: /mitarbeiterprofil/show/3?lang=en
How do I get Grails data binding to correctly bind referenced objects (such as Country in the example below)?
Given the following two Grails domain classes ..
class User {
String username
Country country
}
class Country {
String name
}
.. and the following HTML form ..
<g:form>
<g:textField name="user.username" value="${user.username}" />
<g:select name="user.country" from="${Country.list()}" optionKey="id" />
</g:form>
.. and the following code in the corresponding action ..
User user = new User(params["user"])
.. I would have hoped that user.username and user.country would get bind. However, it appears as if username.username gets bind, whereas user.country is not. What is the correct syntax to bind referenced objects (user.country in this example)?
The binding of the "country" property starts working if ..
<g:select name="user.country" from="${Country.list()}" optionKey="id" />
.. is changed to ..
<g:select name="user.country.id" from="${Country.list()}" optionKey="id" />
You should also look into command objects. They can validate and bind all of your parameters at once.