I want to get value of sec:loggedInUserInfo and attempt into a variable named user.
My code looks like this:
<sec:loggedInUserInfo field="username" />
<%
def user = *value of field loggedInUserInfo *
%>
Is it possible for doing that?
This is simpler and works fine for me:
<g:set var="user" value="${sec.username()}" />
To assign any field of the UserDetails instance referred to by <sec:loggedInUserInfo> to a variable you can use:
<g:set var="fullName" value="${sec.loggedInUserInfo(field:'fullName')}" />
(see also Custom User Details)
If you want the user object in the gsp, just pass it back as part of the model map from the controller. in a controller action do
def user = springSecurityService.getCurrentUser()
render view: 'yourgsp', model: [user: user]
I am not sure if we can use that tag directly, I couldn't find it earlier, so I have made my custom tag for this purpose
<m:userName id="${session.SPRING_SECURITY_CONTEXT?.authentication?.principal?.id}"/>
def userName = { attrs ->
Long id = attrs['id'] ? attrs['id'].toLong() : null
User user = User?.get(id);
out << user?.firstName
}
I have created one taglib as loggedinUser which is added on gsp page as :
Welcome <g:loggedInUser/> !
Which is showing logged In username on top of each gsp in my project. In custom tag library my code is as follows :
def springSecurityService
def loggedInUser={
if(springSecurityService.getPrincipal().equals("anonymousUser")){
response.sendRedirect("${request.contextPath}/login/auth")
}else{
out <<"${springSecurityService.currentUser.username}"
out << """ [${link(controller:"logout"){"Logout"}}]"""
}
}
So it's showing on each page as : Welcome USERNAME[Logout] !
Related
I did this tutorial to use the GSP Template Engine in a Controller to generate a view. Now I want to access to my database inside the html that I have in my controller, but I don't find the good way to do it. I want to access to my column name and template that I have in my domain.
I need to do it of this way, I know that I can do the same with the gsp file.
Controller:
class SendEmailController {
def groovyPagesTemplateEngine
def emailTemplate = {
def templateText = '''\
<html>
<body>
<h1 align="center">Hello</h1>
<p align="center">This is my text</p>
</body>
</html>
'''
def output = new StringWriter()
groovyPagesTemplateEngine.createTemplate(templateText, 'sample').make([show: true]).writeTo(output)
render output.toString()
}
}
DOMAIN
class SendEmail {
String name
String template
static constraints = {
}
}
You can retrieve a domain object in your controller by calling get() (passing in the id of the record you want to retrieve from the database) on the domain object class.
def emailTemplate = SendEmail.get(id).template
There are some other retrieval methods as well. Look at the GORM documentation for more information: https://grails.github.io/grails-doc/latest/guide/GORM.html.
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
My controller is the folowing:
def participated = {
def temp = ConferenceUser.get(params.temp)
def prizes = Prizes.findAllByConferenceUser(temp) // find all rooms where current computer is
def subms = Submissions.findAllByConferenceUser(temp) // find all rooms where current computer is
[temp: temp, priz: prizes, subm: subms]
}
But somehow, when I successfully update a conference value, I wanna go back to the initial page (participated) but I don't know how to pass back the params.temp. (if I do a simple redirect, as the controller is expecting params.temp, it will give me an error because I cannot search prizes with a null object as parameter. So, imagine my update controller is the following:
def update = {
def saveParamshere = params.temp
...
...
(code here)
...
...
redirect(action: "participated", params: [temp: saveParamshere])
}
This code isn't working. How can I successfully go back to my main page and pass in params.temp ?
I think the problem may be, that you are calling update action by submitting form (I suppose). Maybe you are not passing temp value from that form? You can do it by embedding temp as hidden input field into form, or apply it to url by param attribute on form tag.
Using hidden field it might be something like this (in your view file):
<g:form controller="somecontroller" action="update">
(...)
<g:hiddenField name="temp" value="${temp}" />
(...)
</g:form>
Using params attribute:
<g:form controller="somecontroller" action="update" params="[temp : temp]">
(...)
</g:form>
I didn't test any of these so there might be some issues, especially in the second approach.
You could put the params in the flash scope, which lives for two requests, or put them in the session and retrieve them that way.
Here is a link to the grails docs on usage of flash scope:
Grails - Controllers - Controller Scopes
I have a gsp template, where the data for create view is passed through the controller.
def create = {
def bookInstance = new Book()
bookInstance .properties = params
def map = getDefaultValues()
render(template: "create", model: [bookInstance : bookInstance ,
title: map.title,
somelist: somelist
....])
the gsp template
<g:select optionKey="id" from="${somelist}" name="somelist.id" value="${bookInstance ?.somelist?.id}" noSelection="['null': '']"></g:select>
now, in the save method, if there is an error, it returns currently populated and validated instance (default scaffold implementation)
render(template: "create", model: [bookInstance : bookInstance ])
But the fields in the gsp (error page rendered from save action) is empty. I could see the reason as it looks the value in "${somelist}" , but it is not used in save method. Do i just need to check for null in the gsp and use whichever map is available, or any better method (passing all the map in the save method is not an option) ..
thanks in advance..
I figured it out.. I have to pass the same map as was in the create closure .. the reason why we were passing the maps in create is because we wanted to override the default list.. the populated values in bookInstance is only used to preserve the user selection, but not all the values..
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.