Getting an error with sign up [Grails] - grails

i'm with an error that i can't find out how to solve it, i keep getting it when i try do register something
here's the form
<div id="divCadastro"></div>
<g:form controller="aluno" action="save">
<label>Nome:</label>
<g:textField name="nome"/><br>
<label> RG:</label>
<g:textField name="rg"/><br>
<label>CPF:</label>
<g:textField name="cpf"/><br>
<label>RA:</label>
<g:textField name="ra"/><br>
<label>Turma:</label>
<g:textField name="turma"/><br>
<label>Genero: </label>
<select name="genero">
<option value="m">Masculino</option>
<option value="f">Feminino</option>
</select><br>
<label>Código de Barras:</label>
<g:textField name="cod_barras"/><br>
<label>Data de Nascimento:</label>
<g:datePicker name="date" value="${new Date()}" precision="day" noSelection="['':'-Escolha-']"/><br>
<label>Curso:</label>
<g:select name="curso" from="${listaCurso}" optionValue="nome" optionKey="id"/>
<label>Endereço:</label>
<g:textField name="endereco"/><br>
<label>Número:</label>
<g:textField name="nroendereco"/><br>
<label>Telefone:</label>
<g:textField name="telefone"/><br>
<label>Bairro:</label>
<g:textField name="bairro"/><br>
<label>Complemento:</label>
<g:textField name="complemento"/><br>
<label>Cidade:</label>
<g:select name="cidade" from="${listaCidade}" optionValue="nome" optionKey="id"/><br>
<label>Profissão:</label>
<g:select name="profissao" from="${listaProfissao}" optionValue="nome" optionKey="id"/><br>
<label for="escolaridade">Escolaridade:</label>
<g:select name="escolaridade" from="${listaEscolaridade}" optionValue="nome" optionKey="id"/><br>
<input type="hidden" name="id" value="">
<g:actionSubmit value="Salvar"/>
<input type="button" name="btnCancelar" value="Cancelar"/>
</g:form>
and here's the controller:
class AlunoController {
def index() {
def listaAluno = Aluno.list()
def listaCidade = Cidade.list()
def listaProfissao = Profissao.list()
def listaEscolaridade = Escolaridade.list()
def listaCurso = Curso.list()
render(view:"/aluno/index", model:[listaAluno:listaAluno, listaCidade:listaCidade,
listaProfissao:listaProfissao, listaEscolaridade:listaEscolaridade, listaCurso:listaCurso])
}
def save(){
Aluno aluno = new Aluno()
aluno.nome = params.nome
aluno.rg = params.rg
aluno.cpf = params.cpf
aluno.ra = params.ra
aluno.turma = params.turma.toInteger()
aluno.genero = params.genero
aluno.nascimento = params.nascimento
aluno.endereco = params.endereco
aluno.nroendereco = params.nroendereco.toInteger()
aluno.telefone = params.telefone
aluno.bairro = params.bairro
aluno.complemento = params.complemento
aluno.cidade = Cidade.get(params.cidade)
aluno.profissao = Profissao.get(params.profissao)
aluno.escolaridade = Escolaridade.get(params.escolaridade)
aluno.curso = Curso.get(params.curso)
aluno.save(flush:true)
render "Sucesso"
}
}
when i fill up the fields end click on 'Salvar', i get the error:
• Error: Page Not Found (404)
• Path: /aluno/save
what am i missing?
Thanks!
#Edit
i'm using grails 3.1.6 and where's my url mapping:
package eventosunipar
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
"404"(view:'/notFound')
}
}

<g:actionSubmit value="Salvar"/> - actionSubmit is a button to submit to different actions from single form as stated in documentation: http://docs.grails.org/3.1.1/ref/Tags/actionSubmit.html If action parameter is not set in this button, it defaults to value, in your case Salvar. Add action="save" to your button definition or use standard <input type="submit" ... /> tag (I would suggest this option).
If this doesn't work, show generated HTML of the page with form from your browser

Related

Grails - g:field reset and html reset won't clear form/params/session

Using Grails 3.0.9
Making a Clear Form/session button for the filter class. however nothing i do works.
The button is just stuck there, nothing happens
Any help will be appreciated
SupplyController
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
if (params.name)
session.name = params.name
else if (request.method != "POST")
params.name = session.name
else
session.name = null
def criteria = Supply.createCriteria()
def query = {
and{
if (params.name) {
like ("name", '%' + params.name + '%')
}
}
}
def results = criteria.list(params, query)
respond results, model:[supplyCount: results.getTotalCount()]
}
G:field type of code
<div class="filter">
<h3>Filter:</h3>
<g:form action="index" method="post" >
<label for='name'>Name:</label>
<input type="text" id="name" name="name" value="${session.name}"/><br/>
<span class="button">
<g:submitButton name="index" class="index" value="Apply Filter" /></span>
<g:field type="reset" name="myReset" value="Reset" />
</g:form>
</div>
HTML tag type
<div class="filter">
<h3>Filter:</h3>
<g:form action="index" method="post" >
<label for='name'>Name:</label>
<input type="text" id="name" name="name" value="${session.name}"/><br/>
<span class="button">
<g:submitButton name="index" class="index" value="Apply Filter" /></span>
<input type='reset' value='Reset' />
</g:form>
</div>
An HTML form reset button for a form rests the form to the initial state. In this case back to the values it had when the form loaded. A HTML form reset button does not CLEAR the form or CLEAR the session.
wondering why you are using session for where typicalls form params should be used? In order to clear HTML session you would need to trigger a call back to the originating controller just like you would to post but when it receives via this call. It does a session.invalidate() and then renders same view again. You should try to stick with params for forms. The fact that you have the session information already really no need to post it via a form. Your controller receiving the form would be aware of that same session value.
You could easily create a jquery functionality that you do with a button that triggers and a resetform. jQuery/Javascript function to clear all the fields of a form
Or if that does not work you could try for example in your case:
<g:form ..>
..
<button onClick="clearName();" name="clickme">
</g:form>
<g:javascript>
function clearName() {
$('#name').val();
}
</g:javascript>

How to prevent data input for being erase in Grails with reCaptcha

I have gsp with two textfield for firstname-lastname and reCaptcha. What I want is for every wrong captcha code the user's input for firstname and last name won't be erased.
snippet for controller:
***captcha_code****
if (result) {
def person = new Person(params)
person.save()
render "Success!"
} else {
flash.message = message(code: 'forgotPassword.captcha.wrong')
redirect(controller:'person', action:'form')
}
snipper for form.gsp
***captcha_code_here***
<g:form controller="person" action="save">
<label>First Name: </label>
<g:textField name="firstName"/><br/>
<label>Last Name: </label>
<g:textField name="lastName"/><br/>
<g:if test="${flash.message}">
<div class="message" role="status" style="font-size: medium;color: green;">${flash.message}</div>
</g:if>
***captcha_code_here***
<g:actionSubmit value="Save"/>
To repopulate the fields you can use the same flash scope you're using for the message. On error, add the first and last name to the flash scope, and then in your GSP use those values when they are available:
PersonController
class PersonController {
def save() {
...
if(/* recaptcha failed */) {
flash.firstName = params.firstName
flash.lastName = params.lastName
}
...
}
}
GSP
<label>First Name: </label>
<g:textField name="firstName" value="${flash.firstName ?: ''}"/><br/>
<label>Last Name: </label>
<g:textField name="lastName" value="${flash.lastName ?: ''}"/><br/>
In Controller Action, send back fields that you want to be repopulated.

grails g:field error not showing

I have this setup, but the validation is not working
index.gsp:
<g:form name="loginForm" autocomplete="off" controller="company" action ="save">
<table >
<tr>
<td><g:field type="text" name="company" required="true" value="${c?.companyName}" /></td>
</tr>
</table>
Controller:
def index = {
def c =new Company()
//c=params
return [c:c]
}
def save ={}
You need to check for errors using hasErrors method in your form:
<div class="fieldcontain ${hasErrors(bean: yourBean, field: 'yourField', 'error')} required">
<label for="yourField">
<g:message code="yourBean.yourField.label" default="yourField" />
<span class="required-indicator">*</span>
</label>
<g:textField name="content" required="" value="${yourBean?.yourField}"/>
</div>
Grails hasErrors documenttaion.
And check in your controller (save action) if the validation has passed using:
if (!yourBean.save(flush: true)) {
render(view: "create", model: [yourBean: yourBean])
return
}

Grails - 404 File not found - but why?

i start to write a simple login formular. This is the code for the view:
<g:form controller="login" action="checkUsernameAndPassword">
<input type = "text"name="userNameField" value="userName"/>
<input type = "password"name="passWordField" value="passWord"/>
<input type = "submit" name="loginButton" value="Login"/>
</g:form>
this is the code for the controller:
class LoginController {
def index = {
render(view: "login")
}//endMethod Index
def checkUsernameAndPassword = {
[userName = params.userName ,passWord = params.passWord];
}//endMethod checkUsernameAndPassword
}
as you can see, it doesnt do anything yet, i just wanted to print the values on the screen, however i get a 404 message (i run the file on local host)
The requested resource (/projectName/hello/checkUsernameAndPassword) is not available.
I just cant figure out why. Would be great if any of you guys have a tip for me.
beste regards,
Daniel
Edit (Change 1):
def checkUsernameAndPassword = {
render(view: "login",model: [userName: params.userName ,passWord: params.passWord])
}//endMethod checkUsernameAndPassword
}
(Change 2)
//added this line in view
<div>Username: ${userName} Passwort: ${passWord}</div>
<g:form controller="hello" action="checkUsernameAndPassword">
means that you have HelloController with checkUsernameAndPassword action
But in your code sample you have LoginController so to get your form work, you must write:
<g:form controller="login" action="checkUsernameAndPassword">
<input type = "text" name="userNameField" value="userName"/>
<input type = "password" name="passWordField" value="passWord"/>
<input type = "submit" name="loginButton" value="Login"/>
</g:form>
P.S. In Grails world is sometimes much better to use GSP Tags instead of plain HTML because it will generate proper(in 99.99% of cases) HTML code for you.
So the best way to implement your form is:
<g:form controller="login" action="checkUsernameAndPassword">
<g:textField name="userNameField" value="userName" />
<g:passwordField name="passWordField" value="passWord" />
<g:submitButton name="loginButton" value="Login" />
</g:form>
P.S.2 Proper LoginController code(for the form described before)
class LoginController {
def index = {
render(view: "login")
}//endMethod Index
def checkUsernameAndPassword = {
[userName: params.userNameField ,passWord: params.passWordField];
}//endMethod checkUsernameAndPassword

Grails databinding multiple domain classes

HI. I have this classes:
class Carro {
String name
String marca
String matricula
static constraints = {
name(nullable:false, blank:false)
}
static mapping = {
version false
}
}
class CarroMovel {
String move
String rodas
String espelhos
Carro carro
static hasMany = [carros: Carro]
static constraints = {
move(nullable:false, blank:false)
}
static mapping = {
version false
}
}
And the controllers:
class CarroController{
def save2 = {
def carroInstance = new Carro()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
if (carroInstance.save(flush: true)) {
redirect(uri:"/home.gsp")
}
else {
render(view: "/testeAdd", model: [carroInstance: carroInstance])
}
}
And the view testeAdd.gsp
<g:form controller="carro" action="save2">
<h1>Add New Carro Record</h1>
<p>Basic Information</p>
<label>Name
<span class="small">as</span>
</label>
<input type="text" name="name" value="${carroInstance?.name}" /><br>
<label>Marca
<span class="small">as</span>
</label>
<input type="text" name="marca" value="${carroInstance?.marca}" /><br
<label>Matricula
<span class="small">as</span>
</label>
<input type="text" name="matricula" value="${carroInstance?.matricula}" /><br>
<g:submitButton name="save" value="Save" id="oneone"/>
<div class="spacer"></div>
</g:form>
<g:hasErrors bean="${carroInstance}">
<div class="errors">
<g:renderErrors bean="${carroInstance}" as="list" />
</div>
</g:hasErrors>
This is working good. Now i would like to be able to data binding multiple domain classes. So, along with the current code from my gsp file, i would also like to add carroMovel occurrences all in same save2. Im not sure how to do that, specially cause class Carro will need to have an id from class carroMovel. Any help please? Thank you.
I folowed some suggestions and now the results are as follows (im not concerned about error validation yet):
def save3 = {
def carroInstance = new Carro()
def carroMovelInstance = new CarroMovel()
carroInstance.name = params.carro.name
carroInstance.marca = params.carro.marca
carroInstance.matricula = params.carro.matricula
carroMovelInstance.move = params.carroMovel.move
carroMovelInstance.rodas = params.carroMovel.rodas
carroMovelInstance.espelhos = params.carroMovel.espelhos
carroInstance.save()
carroMovelInstance.carro = carroInstance
carroMovelInstance.save()
}
<g:form controller="carro" action="save3">
<h1>Add New Conference Record</h1>
<p>Basic Information</p>
<label>Name
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.name" value="${carroInstance?.name}" /><br>
<label>Marca
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.marca" value="${carroInstance?.marca}" /><br
<label>Matricula
<span class="small">Add your name</span>
</label>
<input type="text" name="carro.matricula" value="${carroInstance?.matricula}" /><br>
<label>Move
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.move" value="${carroMovelInstance?.move}" /><br>
<label>Rodas
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.rodas" value="${carroMovelInstance?.rodas}" /><br>
<label>Espelho
<span class="small">Add your name</span>
</label>
<input type="text" name="carroMovel.espelho" value="${carroMovelInstance?.espelho}" /><br>
<g:submitButton name="save" value="Save" id="addConference"/>
The Carro object is saved in the database, altought, nothing happens with CarroMovel and it is not saved and i can't figure it out.
First I would change the input names to carro.name, carro.marca, carroMovel.move, ... so that they are differentiated by name.
<input type="text" name="carro.name"/><br>
<input type="text" name="carro.marca"/><br>
<input type="text" name="carroMovel.move"/><br>
This has the advantage that the binding in the controller can be done the standard Grails way, and that the correct values are entered in the form without the value attribute set.
carro.properties = params.carro
carroMovel.properties = params.carroMovel
In the controller action you can also save and link the Carro and CarroMovel instances.
carro.save()
carroMovel.carro = carro
carroMovel.save()
if(carroMovel.hasErrors(){
render(view: 'save3', model: [carro: carro, carroMovel.carroMovel])
}
If I understand your question correctly, you can give this a try.
First, edit our form to include the necessary fields for the CarroMovel class,
e.g
<label>Move
<span class="small">as</span>
</label>
<input type="text" name="move" value="${carroMovelInstance?.move}" />
then
in your save2 action,
def carroInstance = new Carro()
carroInstance.name = params.name
carroInstance.marca = params.marca
carroInstance.matricula = params.matricula
def carroMovelInstance = new CarroMovel()
carroMovelInstance.name = params.move
carroMovelInstance.marca = params.rodasa
carroMovelInstance.matricula = params.espelhos
carroMovelInstance.carro = carroInstance
Since Carro does not belong to CarroMovel saving a carroMovelInstance will not cascade to the carroInstance, therefore you will need to save each instance individually before saving its owning instance.
carroMovelInstance.carro.save()
if (carroMovelInstance.save(flush: true)) {
redirect(uri:"/home.gsp")
}
else {
render(view: "/testeAdd", model: [carroInstance: carroInstance, carroMovelInstance:carroMovelInstance])
}
Let me know if that works out for you.
Some of the other answers may be simpler, but I've been using this technique:
http://omarello.com/2010/08/grails-one-to-many-dynamic-forms/
In order for Carro to cascade save the CarroMovel reference, CarroMovel needs belongsTo = Carro or you need to manually tell hibernate to cascade it upon save using something like this:
class CarroMovel{
static mapping = {
carro cascade: 'all'
}
}
Here's the hibernate documentation about cascading:
https://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/metamodel/binding/CascadeType.html
I usually use a command object for this type of thing.
In your controller do something like this:
class CarroController {
def show = {
[cmd: new MyCommand()]
}
def save2 = { MyCommand cmd ->
def carro = cmd.carro
if (carro.save()) {
cmd.movel.carro = carro
if (cmd.movel.save()) {
redirect uri: 'home.gsp'
} else {
// show form again
render view: 'show', model:[cmd:cmd]
}
} else {
// show form again
render view: 'show', model:[cmd:cmd]
}
}
// same file or some other class file
class MyCommand {
Carro carro
CarroMovel movel
}
}
You will need to adjust your form a bit as well...
Where you have "Carro" fields reference them like this:
<input type="text" name="carro.matricula" value="${cmd.carro?.matricula}" />
Where you have the "CarroMovel" fields, like this:
<input type="text" name="movel.rodas" value="${cmd.movel?.rodas}" />
This code might not be exactly right (I didn't test it), but should get you down the correct path. Also instead of referencing the objects in the command object, you could just have the fields that you are binding, and then build the actual domain objects from them, either through a helper method (def buildCarro(){...}) or by hand in the controller method.

Resources