I'm completely new to grails, and I appreciate any help.
This code is in my gsp file:
<g:form action="backfillMachineTags">
<fieldset class="buttons">
<g:submitButton name="create" class="save"
value="${message(code: 'default.button.create.label', default: 'Create')}"/>
</fieldset>
</g:form>
And this code is in my RegressionPoolMachineController.groovy file:
def backfillMachineTags()
{
flash.message = "testing message"
redirect(action: "list")
}
But when I click the submit button on the form, the method is never entered and I get a 404 not found.
message:/pool-manager/regressionPoolMachine/backfillMachineTags
status: The requested resource is not available.
I also tried doing:
<g:form url="[action:'backfillMachineTags',controller:'RegressionPoolMachineController']">
but get a similar 404 not found.
Am I missing a step to connect my form and controller?
Try to use the following:
<g:form controller = "controllerName" action ="actionName" >
<fieldset class="buttons">
<g:submitButton name="create" class="save" value ="${message(code: 'default.button.create.label', default: 'Create')}"/>
</fieldset>
</g:form>
Try adding a "controller" attribute to your form in addition to the "action" attribute. You could use url instead of controller and action, but you would need something like
url="${createLink(controller: "myController", action: "myAction")}" instead of what you've shown here.
For reference: http://docs.grails.org/2.5.6/ref/Tags/form.html
You can also look at the generated HTML in your browser (just view source) and see what is actually being generated on the resulting web page. That's usually pretty helpful for finding out why things aren't going where you want them to!
Related
I am trying to make a simple creation of account and when create button is clicked it should perform the action "create" but I get an error saying that
HTTP Status 404 - "/WEB-INF/grails-app/views/users/create.gsp" not found.
Here is my code block for the index.gsp
<!-- CREATEFORM -->
<div id="id02" class="modal">
<g:form class="modal-content animate" controller="users" action="create">
<div class="imgcontainer">
<span onclick="document.getElementById('id02').style.display='none'" class="close" title="Close Modal">×</span>
<div class="container" style="text-align:center">
<b><h style="font-family: Arial, Helvetica, sans-serif; font-size: 30px">CREATE AN ACCOUNT</h></b><br/>
<input type="text" placeholder="Enter Username" name="uname" required/>
<input type="password" placeholder="Enter Password" name="psw" required/>
<input type="text" placeholder="First Name" name="firstName" required/>
<input type="text" placeholder="Last Name" name="lastName" required/>
<input type="text" placeholder="Age" name="age" required/>
<br/>
<input type="date" placeholder="Birth Date" name="birthdate" required/>
<br/>
<input type="text" placeholder="Student Number" name="studno" required/><br/>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me</input>
</label>
<br/>
<button type="submit" style="width: 100px; margin-right:10px;" >Create</input>
<button type="button" onclick="document.getElementById('id02').style.display='none'" class="cancelbtn">Cancel</button>
</div>
</div>
</g:form>
</div>
and Here is my code block for the usersController.
class usersController {
def index(){}
def create()
{
new Users(userid:params.uname,password:params.psw).save()
new UserInfo(studentno:params.studno,age:params.age,birth_date:params.birthdate,first_name:params.firstName,last_name:params.lastName,user_id:params.uname).save()
}
}
And here's the error
HTTP Status 404 - "/WEB-INF/grails-app/views/users/create.gsp" not found.
Because you are saving data using create action but after saving data there is no redirect option or create.gsp available. So grails will look first is there any redirect option available and try to redirect create.gsp
Check bellow code changes which will save user id to userInfo table and redirect to index page
So change your usersController
class usersController {
def index() {}
def create() {
def user = new Users(userid: params.uname, password: params.psw).save()
def userInfo = new UserInfo(studentno: params.studno, age: params.age, birth_date: params.birthdate, first_name: params.firstName, last_name: params.lastName, user_id: user.id).save()
if (user && userInfo) {
flash.message = "User created successfully"
redirect action: 'index'
} else {
flash.message = "Problem in user creation"
redirect action: 'index'
}
}
}
And add bellow code to your index.gsp
${flash.message}
There are many ways to redirect to pages. You can use render, redirect, chain, forward ..etc
Please check grails documentation for more information
In Grails for action (non gsp) you need to render something to the client,
otherwise it executes everything inside that action, but returns 404 gsp not found response, if there is no render / redirection statement it consider that action as a gsp but it is not gsp actually, therefore it responds 404.
You could render something data like list / JSON or simple string as follows.
def create() {
//your business logic is here
render "operation performed successfully"
}
First of all what grails version do you use? If the latest one (3.3.4) so this link might be helpful.
Speaking shortly: if you don't specify what to render explicitly - grails tries to find the view to display the result of action execution as:
grails-app/views/<controllerName>/<actionName>.gsp
Looks like you don't have one.
UPD
There are several ways to render action's output in grails controller.
Define explicit content as:
def myAction() {
...
render "Hello World!"
}
That will result in "white screen" with "Hello world!" text in top-left corner.
Another option is to create a gsp view in the conventional location as grails-app/views//.gsp - it will automatically be rendered after action execution if no specifying the render method invocation (like in the sample you've given)
The third option is to specify the model map:
def myAction() {
...
[param1key: param1value, param2key: param2value, ...]
}
The model will be taken into account when rendering your gsp view.
Please read the documentation I gave link to. It's incredibly helpful.
Recently I began to study Grails, and I noticed that the file create.groovy is generated by a dynamic scaffold. The form tag doesn't have an attribute called controller, only action.
So my question is, how does the Grails framework discover the controller that should be called?
<g:form action="save">
<fieldset class="form">
<f:field bean="categoria" property="nome" class="form-control" />
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
Thanks, and sorry for my bad english!
Grails uses "convention over configuration" so whenever you use a form without controller, grails will use the default convention.
Since your view is put in a folder named after a controller, grails will assume that the default controller for any view inside that folder is the one that matches with the folder name. Example
BookController is the default controller for any gsp inside the grails-app/views/book folder.
*This convention also applies to things like links.
The bean class looks like this:
String houseNo
String address
Person person
The view looks like this
<g:form action="save">
<fieldset class="form">
<g:render template="form" />
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save"
value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
According to my knowledge in Grails, i think is <g:render template="form" /> will pull all form attributes and display it.
But what i want to do is Instead of displaying a drop-down for Person, i want to display all Person related fields like personName, personAge. How can i display these fields in a label underneath ?
Help
You're correct about the way g:render works, the template part refers to a GSP which will look through the bean values and print them according to the html + groovy markup in "_form.gsp" (located in your views folder under the controller name).
To change the way the Person domain object is displayed, simply edit this "_form.gsp" and take out the 'select' html code - replacing it with groovy markup using the property values of the bean, eg.
${beanName.person.personName} //(use the existing code to help workout the bean name etc)
Hopefully that helps you on your way.
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
Hi All,
I have an edit button
<span class="button"><g:actionSubmit class="edit" action="edit" value="${message(code: 'default.button.edit.label', default: 'Edit')}" /></span>
But when click on it the adderess on the browser was not http:\...\edit,
it was http:\...\index. Why?
I tried to delete or rename the name of Edit in controller, it still not influence. Why?
Thanks!!!
Try specifying controller's name with g:form like
<g:form controller="CONTROLLER_NAME">