Iam formRemote in a gsp and calling a controller method, inside that method iam calling a sevice class and there iam doing my save action. But the problem is my update div is not working after a successful saving
You form should like this
<g:formRemote method="post"
update="updateThisDiv"
name="formRemote" url="[ controller: 'main', action:'myAction']">
//your form fields
</g:formRemote>
<div id="updateThisDiv"></div>
"updateThisDiv" is the id of an html-object, that you want to render after submit (but it's not mandatory).
Controller
def myAction() {
//TODO: your logic..
render "Your view" //you can render jsp view, json etc..
}
Related
I'm creating a Grails app following this tutorial: http://grails.asia/grails-tutorial-for-beginners-display-data-from-the-database
When I try to display data from database though, nothing happens. Below is my controller code:
def index(){
def users = User.list();
[users:users]
}
def displayUsers(){
if(User.count()==0){
render 'User list is empty!';
}else {
render(view: 'userlist.gsp');
//a little test
println User.list().size();
println User.count();
for(User u : User.list()){
println u.username;
}
}
}
The User.count() is working, because I can see the usernames in console and userlist.gsp renders every time, but it seems that my view code doesn't see the list. Here's the userlist.gsp code:
<body>
userlist.gsp
<g:each in="${users}" var="user" status="i">
<h3>${i+1}. ${user.username}</h3>
</g:each>
</body>
What can be wrong with this code? I've been making precisely the same steps as in the tutorial above in my analogical app, but it doesn't seem to work. This is especially weird, since I've found a similar question under this link: grails: show list of elements from database in gsp
and it's been marked as accepted answer. Why does exacly the same way not work in my app?
render gsp view as follows (pass data as a model).
render(view: "userlist", model: [userList : User.list()])
Now get model data in gsp as follows.
<body>
userlist.gsp
<g:each in="${userList}" var="user" status="i">
<h3>${i+1}. ${user.username}</h3>
</g:each>
</body>
You can do with many options:
rename your gsp action in controller from def index() to def userlist()
or rename index.gsp file to userlist.gsp
you can redirect to userlist.gsp with ${users} object
So change in controller def index() action
[users:users] to redirect(action: "userlist", params: ["users": users])
Note: 2nd method will show parameters in url.
Refer Grails Doc
You can use chain
e.g. chain(action: "userlist", model: ["users": users])
Refer Grails Doc
every gsp action (page) needs to be injected
This is the code I am using in the gsp file to fetch the data to show on the view page:
<datePicker id="startDate" name="startDate" value="${new
Date().minus(2).format('yyyy-MM-dd')}" />
the datepicker I am using in the same page.
Now i need to pass the datepicker parameters to this link
<a id="exportIcon" href="${createLink(controller: entityName, action:
'mrInventoryExcelExport', params: [StartDate:startDate])}" >
the parameter is the startdate which i enter manually in the form
Can anyone tell me how can i achieve this.
You could just use a button & submit the form to the given action then either deal with it in the action directly:
gsp:
<g:actionSubmit name="exportIcon"
action="mrInventoryExcelExport"
value="Export"/>
controller:
def mrInventoryExcelExport() {
def startDate = params.startDate
...
}
Or redirect to another action with the startDate:
gsp:
<g:actionSubmit name="exportIcon"
action="anotherAction"
value="Export"/>
controller:
def anotherAction() {
redirect( controller: 'entityName', action: 'mrInventoryExcelExport', params:[startDate: params.startDate] )
}
You need to understand the mechanics. GSP is a server-side technology. Whatever related you have in there, will be processed and converted to HTML, before it is sent to the client/browser.
Now, what you're asking to include/change a parameter in the link, based on the value picked by user; mind you, the link is already created. No chance? Using JavaScript to create that link is your best bet.
P.S.: Try to see the page source from the browser, for more insight.
new.gsp:
<html>
<head>
</head>
<body>
<g:form name="myForm" controller="New" action="index" params="username:username">
<div>
<fieldset class="form">
<label for="name">Name:</label>
<div>
<g:textField name="username" value="${params.userName}"/>
</div>
</fieldset>
</div>
<g:submitButton name="Submit" value="Submit" />
</g:form>
</body>
<html>
NewController.groovy:
package sample
import com.sun.org.apache.bcel.internal.generic.NEW;
class NewController {
def index = {
if($params.userName){
render(view:"/login.gsp")
}
}
}
login.gsp is a simple page, having a simple welcome note.
if some body the solution please reply,
thanks in advance.
by prasanth
Change your controller name to "new" instead of New in
It will work.
Or else you can modify your "save" action in controller, so that when you click on save button new page will be rendered.
There are a few issues in the posted code that will cause you problems:
You're accessing the parameters with $params instead of params. The $ character is only necessary when you are in a GString. e.g. def foo = "your username is ${params.userName}"
Your view is named new.gsp but your action is named index. Grails will by default look for a view matching the action name in a directory named for the controller. In other words, since you don't tell it explicitly to render /new.gsp grails will look for /new/index.gsp. You can either rename the view to /new/index.gsp or tell grails to render the view new in the index action.
When attempting to render your logged in page, you're calling render(view: 'login.gsp'). The gsp extension is not necessary when calling the render tag. You're intended to use the grails view name, not the filename. render(view: 'login')
If you're using a recent version of grails (>2.0) you should be using controller methods rather than closures. e.g. def actionName() { } as apposed to def actionName() = { }. The reasoning is in the grails documentation.
Here's what it could look like with all the issues addressed:
rename new.gsp to /new/index.gsp. rename login.gsp to /new/loggedIn.gsp.
controller:
class NewController {
def index() {
if (params.userName) {
forward action: 'loggedIn'
return // render and forward don't end flow control
}
}
def loggedIn() {} // no logic, automatically renders '/new/loggedIn.gsp'
}
Add a handler to your controller named login.
def login = {}
If the view file is new.gsp then you need your action to also be new or else have a URL mapping (in UrlMappings.groovy) to do something like:
"/new" {
controller = 'new'
action = 'new'
}
Or you can set
static defaultAction = 'new'
...in your NewController.
Then Grails will find the appropriate action on your controller.
if your action is called index, you can acces the page on
localhost:8080/webapp/NewController
I have table in UI which is populated by values from database. Now I want to call a controller action Onclick of table row and render to different view.
I tried following code function is getting executed properly but its not rendering to different view.
In GSP:
<tr onclick="<g:remoteFunction controller="LeaveApplied" action='getLeaveDetail' id='${it.id}'/>">
controller:
def getLeaveDetails(){
def leaveObj = leaveAppliedService.getLeaveDetail(params.id)
println "leave: "+leaveObj
render(view:'respond', model: [leave:leaveObj])
}
Any Answers will be thank full.
if you want to update your table with an ajax call, you can try this:
GSP:
onclick="<g:remoteFunction controller="LeaveApplied" action="getLeaveDetail" params="[id: it.id]" update="target_div" />"
Controller:
def getLeaveDetails(){
def leaveObj = leaveAppliedService.getLeaveDetail(params.id)
render(template:'respond', model: [leave:leaveObj])
}
Haven't tested the code, but the important things are to set the params and update Attributes in your GSP and to render a template instead of a view.
I am trying to create a simple portlet for Liferay 5.2.2 using Grails 1.2.1 with the grails-portlets 0.7 and grails-portlets-liferay 0.2 plugins.
I created and deployed a stock portlet (just updated title, description, etc...). It deploys correctly and the view renders correctly. However, when I submit the default form that is in view.gsp it never hits the actionView function.
Here are the relevant code bits:
SearchPortlet.groovy
class SearchPortlet {
def title = 'Search'
def description = '''
A simple search portlet.
'''
def displayName = 'Search'
def supports = ['text/html':['view', 'edit', 'help']]
// Liferay server specific configurations
def liferay_display_category = 'Category'
def actionView = {
println "In action view"
}
def renderView = {
println "In render view"
//TODO Define render phase. Return the map of the variables bound to the view
['mykey':'myvalue']
}
...
}
view.gsp
<%# taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
<div>
<h1>View Page</h1>
The map returned by renderView is passed in. Value of mykey: ${mykey}
<form action="${portletResponse.createActionURL()}">
<input type="submit" value="Submit"/>
</form>
</div>
The tomcat terminal prints In render view whenever I view the portlet, and after I press the submit button. It never prints the In action view statement.
Any ideas?
Update
I turned on logging and this is what I see whenever I click the submit button in the portlet:
[localhost].[/gportlet] - servletPath=/Search, pathInfo=/invoke, queryString=null, name=null
[localhost].[/gportlet] - Path Based Include
portlets.GrailsDispatcherPortlet - DispatcherPortlet with name 'Search' received render request
portlets.GrailsDispatcherPortlet - Bound render request context to thread: com.liferay.portlet.RenderRequestImpl#7a158e
portlets.GrailsDispatcherPortlet - Testing handler map [org.codehaus.grails.portlets.GrailsPortletHandlerMapping#1f06283] in DispatcherPortlet with name 'Search'
portlets.GrailsDispatcherPortlet - Testing handler adapter [org.codehaus.grails.portlets.GrailsPortletHandlerAdapter#74f72b]
portlets.GrailsPortletHandlerAdapter - portlet.handleMinimised not set, proceeding with normal render
portlet.SearchPortlet - In render view
portlets.GrailsPortletHandlerAdapter - Couldn't resolve action view /search/null.gsp
portlets.GrailsPortletHandlerAdapter - Trying to render mode view /search/view.gsp
portlets.GrailsDispatcherPortlet - Setting portlet response content type to view-determined type [text/html;charset=ISO-8859-1]
[localhost].[/gportlet] - servletPath=/WEB-INF/servlet/view, pathInfo=null, queryString=null, name=null
[localhost].[/gportlet] - Path Based Include
portlets.GrailsDispatcherPortlet - Cleared thread-bound render request context: com.liferay.portlet.RenderRequestImpl#7a158e
portlets.GrailsDispatcherPortlet - Successfully completed request
The fourth line in that log snippet says Bound render request..., which I don't understand because the action in the form that is in the portlet is to the action url. I would've thought that should be an action request.
I have this same issue and it would be very nice to get it working.
UPDATE
I added method="post" to the form and it worked like a charm :)