g:select onchange with rest-url - grails

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

Related

Grails form submit causes 404

I have created a very simple form for signing up a user
<g:form name="signupForm" url="[controller:'users', action:'signup']">
<g:textField name="username" placeholder="Username" />
<g:passwordField name="password" placeholder="Password" />
<g:textField name="email" placeholder="Email" />
<g:actionSubmit class="right" value="Signup" action="update" />
</g:form>
When I click the submit button I get a 404 error The requested resource is not available. However, if I navigate to the exact same URL manually (or even just select the address bar on the 404 error page and press enter) then it works!
My controller looks like this, it's very simple.
class UsersController {
def signup() {
render "Hello World"
}
}
Sorry if this is a noob question, but I've looked all over the Grails docs and can't figure out why this is happening. Any help much appreciated. Thanks.
The g:actionSubmit has the parameter action="update" which will push it to the UsersController def update which isn't there so it will throw a 404.
You can remove the action="update" or add that action to the controller.
http://grails.org/doc/latest/ref/Tags/actionSubmit.html
There is also a g:submitButton you can use instead.
http://grails.org/doc/latest/ref/Tags/submitButton.html

Grails populating a domain instance

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.

Grails Export Plugin Doesnt Work with namedQuery

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.

asp.net mvc redirect to action and passing a parameter from user input

I have a page with a input box and a button, when the user clicks the button i want to redirect to a controller action that has as parameter the value of the input box.
<input id="CodProiect" type="text" />
<input id="Cauta" type="button" value="Cauta" onclick="window.location.href='#Url.Action("Cauta", "Componente", new { CodProiect = "param" })';"/>
How can i get the "param" from the input box ?
You could just use a form with a GET method
<form action="#Url.Action("Cauta", "Componente")" method="GET">
<input id="CodProiect" name="CodProiect" type="text" />
<input id="Cauta" type="submit" value="Cauta" />
</form>
The form will add the parameter as part of the query string of the URL e.g. www.yoursite.com/Cauta/Componente?CodProiect=user+entered+value
Value of the Action is prepared at server side and sent to the browser so you cannot have the value at the server when it is a user input.
You can use jquery to change the URL at client side.
Also passing state in an PRG scenario is a common problem in ASP NET MVC. You can either:
Store it temporarily in session
Pass it as a parameter in URL
Use a form.
Form:
<form action="Componente/Cauta">
<input id="CodProiect" type="text" />
<input id="Cauta" type="submit" value="Cauta" />
</form>
Controller:
public ActionResult Cauta(string CodProiect)
{
//Do some stuff
}
More info: http://weblogs.asp.net/scottgu/archive/2008/09/02/asp-net-mvc-preview-5-and-form-posting-scenarios.aspx
Syntax may be outdated, but you get the point...

Use the routing engine for form submissions in ASP.NET MVC Preview 4

I'm using ASP.NET MVC Preview 4 and would like to know how to use the routing engine for form submissions.
For example, I have a route like this:
routes.MapRoute(
"TestController-TestAction",
"TestController.mvc/TestAction/{paramName}",
new { controller = "TestController", action = "TestAction", id = "TestTopic" }
);
And a form declaration that looks like this:
<% using (Html.Form("TestController", "TestAction", FormMethod.Get))
{ %>
<input type="text" name="paramName" />
<input type="submit" />
<% } %>
which renders to:
<form method="get" action="/TestController.mvc/TestAction">
<input type="text" name="paramName" />
<input type="submit" />
</form>
The resulting URL of a form submission is:
localhost/TestController.mvc/TestAction?paramName=value
Is there any way to have this form submission route to the desired URL of:
localhost/TestController.mvc/TestAction/value
The only solutions I can think of are to create a separate action that just checks the request parameters, or to use Javascript.
Solution:
public ActionResult TestAction(string paramName)
{
if (!String.IsNullOrEmpty(Request["paramName"]))
{
return RedirectToAction("TestAction", new { paramName = Request["paramName"]});
}
/* ... */
}
In your route, get rid of the {paramName} part of the URL. It should be:
TestController.mvc/TestAction
As that is the URL you want the request to route to. Your form will then post to that URL.
Posted form values are mapped to parameters of an action method automatically, so don't worry about not having that data passed to your action method.
My understanding is that this is how HTML works. If you do a <form url="foo" method="get"> and post the form, then the form will post foo?
param1=value1&...&paramn=valuen
It has nothing to do with MVC.
Besides, what part of REST does that URL violate? It's not a pretty URL, but by strict definition of REST, it can be RESTful. REST doesn't specify that query parameters have to be in an URL segment. And in this case, those are query parameters.

Resources