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
Related
Can we implement PageRender in controller (grails 3.2.8)? I tried in a service and it worked perfectly as expected.
But when I tried in a controller, I am not getting the expected results.
Controller:
class TestcontrollerController {
def RenderService
def gsp= "grails"
PageRenderer groovyPageRenderer
def index(String gsp) {
render creategsp()
}
def creategsp() {
groovyPageRenderer.render view: '/email/confirm', model: [gsp: findgsp()]
}
def findgsp() {
'<g:select from="${18..65}" value="${age}" />'
}
}
index.gsp:
<g:render template="/test/samplePage" />
samplePage.gsp:
<g:render template="/email/welcome" />
_display.gsp:
Hi ,{username} <br>
PageRenderer is not rendering any of the custom tags or grails tags.
Any suggestions?
Yes this is completely possible. Just define it at the top of your controller:
PageRenderer groovyPageRenderer
Note that you need to strongly type this, and not just "def" it.
Then when you use it, it will render pages to strings:
String renderViewResult = groovyPageRenderer.render(view: "/myViewName", model: renderModel)
If you update your question with more details like what you did, and what isn't working, possibly someone can help you more, but big picture: yep, it works!
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..
}
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've got a controller, which is getting a list of objects associated with a user and passing it to the view using the render method, like so:
class HomeController {
def index() {
def postList = user.posts
postList.each{ it ->
println "Title: " + it.title
}
render(view: "/index", model: [returnPosts: postList])
}
In my view I have the following code:
<h2>Recent Posts:</h2>
<ul>
<g:each var="post" in="${returnPosts}">
<li><g:link controller="post" action="show" id="${post.id}">${post.title}</g:link></li>
</g:each>
</ul>
Now, in my controller, I've put in the 'println' statements to ensure that the list is not null, and sure enough it's not. However, when I open the page, the g:each tag doesn't run even once as if the "returnPosts" variable is null, even though in the controller the println statments show that it's not.
I've been going crazy trying to figure this out, can anyone see any reason why the view wouldn't have access to this variable?
You seem to have a controller attribute called 'post' and also your g.each var is 'post'. Potential problem there?
There are couple of things you could do to fix this problem. Firstly, if your view is called index.gsp then you don't need to explicitly call render, returning a list of model objects would do. Your code will look like this:
def index() {
def postList = user.posts
postList.each{ it ->
println "Title: " + it.title
}
[returnPosts: postList]
}
Another thing you could also do is to explicitly import the model object that you are accessing in the view. Not that it matters, but you could try using a name other than post, given that it is a common word. So your gsp will look like this :
<%# page import="com.blah.post" %>
<h2>Recent Posts:</h2>
<ul>
<g:each in="${returnPosts}" var="post">
<li><g:link controller="post" action="show" id="${post.id}">${post.title}</g:link></li>
</g:each>
</ul>