Grails - URL mapping/default action and flow - grails

Question -
I've noticed that some applications I test with have calls to another view/controller from an action submit, but when that page is rendered, instead of seeing:
$controller/$page
I see:
$controller/index
Is this an issue with the URL mapping configuration? Default action? Just curious, because it just appears to be the URI mapping to a default instead of the actual action.
view code:
<table>
..
<g:actionSubmit class="stats" action="stats" value="View Stats"/>
..
</table
controller:
def stats() {
def teamId = Team.get(params.id)
def allPlayers = Player.withCriteria {
eq('team', teamId)
and {
eq('isActive', true)
}
}
[allPlayers:allPlayers, teamId:params.id]
}
UrlMapping:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
}
Edit
I actually figured out what it is. Which makes me even more confused.
The grails actionSubmit has an action tied to it. That form was just a normal form, without call:
<g:form>
<g:actionSubmit class="stats" action="stats" value="View Stats"/>
<g:actionSubmit class="schedule" action="schedule" value="View Schedule"/>
<g:form>
So by default, the form redirects the action to $controller/index. If you add an action call in the g:form tag, those two buttons will direct to the correct page, but the URI will now be $controller/$g:form_action.
I guess I don't get the point of the actionSubmit's action if the g:form is needed as a wrapper.

Yes, index is the default action for all controllers. So if you do not specify one, that is the page you will land on for the controller.
It is discussed in further detail on their website. Namely, the rules are:
If only one action is present the default URI for a controller maps to
that action.
If you define an index action which is the action that
handles requests when no action is specified in the URI /book
Alternatively you can set it explicitly with the defaultAction property:
static defaultAction = "list"

Related

how to pass one parameter value from admin controller to reports controller in grails

i want to pass caterer value from admin controller to reports controller
getreports.gsp
<g:form url="[admin:catererInstance, action:'save']" >
<div value="${adminInstance.caterer}"></div>
</g:form>
reportscontrooler.groovy
class ReportsController {
def index() {
redirect(action: "_getreports", params: params)
}
def _getreports(){
def adminInstance=new Admin(params)
def adminList=Admin.list().caterer
render(template:"getreports",model:[adminInstance:adminInstance])
}
}
I have modified your code and simply explain how to pass value to controller from your getreports.gsp
getreports.gsp
<g:form url="[admin:catererInstance, action:'save']" >
// Click SEND Button to send value to getreports action
<g:link class="btn btn-info btn-sm" action="getreports" resource="${adminInstance}">SEND</g:link>
</g:form>
reportscontrooler.groovy
// import your admin class here.
class ReportsController {
def index() {
redirect(action: "_getreports", params: params)
}
def _getreports(Admin adminInstance){
// You can get your values Here.
println "adminInstance: "+adminInstance
}
}
You say you have two controllers, but your code shows both of your methods in ReportsController only. If that is the case, you should use forward instead of redirect. If you really meant to issue a redirect to AdminController from ReportsController, then you need to supply controller parameter in your redirect.
Although, this should do the trick, I highly suggest you not to use a redirect here. Better create a new service, maybe ReportsService and move your _getReports() method there. Ideally, services should be handling all your business logic, not controllers.

Controller is there, but showing "Error code 404 page not found" in grails

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

Ambiguous route ordering

I have two ambiguous routes, both within the same MVC area:
Default
{controller}/{action}/{id}
controller = "Home"
action = "Index"
id = Optional
SettingsRoute
Settings/{controller}/{action}
action = "Index"
I want MVC to use the Default route by default, which it does when the routes are in the order specified above. So this...
Controller: WelcomeController
Action: Login
using( Html.BeginForm() ) { }
...results in this HTML
<form action="/Welcome/Login" method="post"></form>
So far, so good.
However when I have an anchor that looks like this:
Application settings
...it gets captured by the Default route as Controller = Settings, Action = AppSettings instead of by the SettingsRoute route.
When I reorder the routes so SettingsRoute appears before Default then my Html.BeginForm() calls look like this: <form action="Settings/Welcome/Login"> which isn't what I want at all.
Is there any solution to this?
You Can mention <%:Html.ActionLink("Create Item-->this is the page you wanted to redirec ","Index","Item--> folder of the page") %>
You can Navigate from one page to another.

Unable to decode the urlMapping in Grails application

Problem:
I am able to execute the default action(listLatest) of my Controller(ReviewMetricsController). But, I am not able to explicitly invoke other action(index) with form submission.
I am using Grails 2.0.4 and running my application in development mode from Eclipse IDE with Grails plugin installed.
Detail:
I have a form in my gsp as shown below
<g:form name="queryForm"
url="[controller:'reviewMetrics', action:'index']">
<g:actionSubmit value="submit" />
</g:form>
When I submit the above form, I get 404 error
The requested resource (/reviewmetricsapp/reviewMetrics/index) is not available
My Controller(reviewMetricsController.groovy) looks as shown below
package reviewmetricsapp
class ReviewMetricsController {
static scope = "session"
static defaultAction = "listLatest"
def gatherMetricsService
def grailsApplication
def latestMetrics
def index() {
render(view:"dashboard", model: [model: latestMetrics])
}
def listLatest(){
println grailsApplication.config.metricsapp.perlScript.loc
latestMetrics = gatherMetricsService.getLastWeekMetrics()
println "printing ${latestMetrics}"
render(view:"showMetrics", model: [metrics: latestMetrics])
}
}
And my urlMappings.groovy looks as shown below
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{ constraints {
// apply constraints here
} }
"/reviewMetrics/index"{
controller="reviewMetrics"
action="index"
}
"/"(view:"/index")
"500"(view:'/error')
}
}
Any help is appreciated
You do not need to change the URLMappings-file for your use-case. (remove the special case handling for reviewMetrics/index - its handled from the first rule)
Please use the following form definition:
<g:form name="queryForm"
controller="reviewMetrics"
action="index">
[..]
</g:form>
Please double check that your action is not accessed - simply put a plain index.gsp and do not care inside the controller. I guess the error is somewhere else.

Grails controllers pass parameters

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

Resources