Problems with form gsp - grails

I'm trying to send parameters from my form (gsp) to my controller grails, but doesn't work.
<g:form url="[action:'searchByFilter', controller:'invoice']" method="GET">
<p>Filtro de busca</p>
<g:textField name="search" value="${invoice?.search}" params="search : search"/>
<g:submitButton name="search" class="input-search" value="${message(code: 'default.button.search.filter')}" />
</g:form>
I need to send input's value to do a result's filter. But, input's value isn't sending.
My domain class code:
static namedQueries = {
getInvoicesByStatus {
eq 'deleted', false
}
getInvoicesByFilter {
eq 'description', Invoice.get(params.search)
}
}
What's my mistake? I need to use namedQuery :)

Related

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.

Creating a view with Domain object fields

I have the following domain classes.
Address
String number
String roadName
String country
Person
String fName
String age
Address address
I have a view called PersonViewSave i want the user to be able to save Person information from this view. When creating a Person record the user needs to create a Address record as well.
My Person controller looks like this:
PersonViewSave ={
def ad = new Address(number: '11', roadName: 'round road', country:'France').save()
new Person(fName: 'Alex', age: '23', address:ad).save()
}
1.) How do i collect parameters from the view and bring it to the PersonViewSave method ? (And can someone show me a sample GSP view file with the Person and Address textfields)
2.) Incase if there's an error in the Address created, how do i prevent creating a Person object with an address as shown in this line new Person(fName: 'Alex', age: '23', address:ad).save()
UPDATE
<g:form name="myForm" method="post" action="doIt">
<p>Person info:</p>
<label for="firstName">First Name</label>
<g:textField name="firstName" id="firstName" />
<p>Address Info:</p>
<label for="roadName">Street Number</label>
<g:textField name="roadName" id="roadName" />
<g:submitButton name="submit" value="Submit" />
Here, i have only used few objects from the Domain classes just to see if it works.
I also have a parameter called createdDate in both Domain classes. That as well needs to be auto inserted.
My Service Class is as follows:
def saveService () {
def ad = new Address(params)
if (ad.save(flush: true)) {
def p = new Person(params)
p.address = ad
p.save()
} else {
// display validation errors
}
}
1.) I get an error and it is > No such property: params for class: pro.PersonService
2.) What hapence i have 2 domain class with parameters that has the same Name. For example Animal and Person domain classes have an parameter called firstName. According to your previous solution how will grail distinguish to what domain class it belongs to ?
I am using Grails 2.2.4
Here is a way to check that the Address saved correctly:
def ad = new Address(params)
if (ad.save(flush: true)) {
def p = new Person(params)
p.address = ad
p.save()
} else {
// display validation errors
}
This returns the Address if it saved properly, which results in true, otherwise it returns null (or false).
Also, you can use data binding via the params map to create your objects from parameters. As long as the key in params matches up to a property name in your Address and Person class, the value of the parameter will be assigned to the object.
So, for instance, to map your Person, you will need fields like the following:
<g:form name="personForm" method="post" action="PersonViewSave">
<p>Person info:</p>
<label for="fName">First Name</label>
<g:textField name="fName" id="fName" />
<label for="age">Age</label>
<g:textField name="age" id="age" />
<p>Address Info:</p>
<label for="number">Street Number</label>
<g:textField name="number" id="number" />
<label for="roadName">Road</label>
<g:textField name="roadName" id="roadName" />
<label for="country">Country</label>
<g:textField name="country" id="country" />
<g:submitButton name="submit" value="Submit" />
</g:form>
you can try this
def ad = new Address(number:params.number , roadName:params.roadName , country: params.country)
if (ad.save(flush: true)) {
def p = new Person(fName:params.fName , age: params.age, address:ad)
p.save()
} else {
// display validation errors
}

Getting a value from g:select in Grails

I'm trying to create my own 'edit' form in my grails application.
My g:select is currently populated with stuff from my database and looks like this:
<g:select name="nameList" from="${Card.list()}" value="${name} " />
And then the value :
<g:field name="amount" type="number" value="" required=""/>
My domain has only two variables - name and amount. I want to select the item from the dropdown box, type in the amount and just click 'update', my update method is a default one generated by grails so it requires ID and Version, how would I go about passing it through?
My update button ;
<g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />
My domain code:
package cardstorage
class Card {
String name;
int amount;
static constraints = {
name(blank:false);
amount(blank:false);
}
String toString(){
return name;
}
}
Thank you
I have fixed it but I'm sure it is not a proper way to do so.
<g:form method="post" >
<g:select name="card" from="${Card.list()}" optionValue ="name" optionKey="id" />
<g:field name="amount" type="number" value="" required=""/>
<fieldset class="buttons">
<g:actionSubmit class="save" action="update" value="${message(code: 'default.button.update.label', default: 'Update')}" />
</fieldset>
</g:form>
thats my code for the g:select. In my Controller method, passing the value of 'card' to the 'Long id' would result in 'id' being 49 (null + 1 = 49?)
def update(Long id, Long version) {
id = params.card;
id = id- 48;
...
}
Now I'm able to update my records, however I'm curious how should I have done this more properly.

How to use Grails Searchable plugins in more than 2 domains

I am completely new in Grails, start learning grails from past couple of days. I am trying to add search feature by using searchable plugin in my demo grails application. I successfully added searchable plugins on user search where user can search other users and follow them. I am doing like this ..
grails install-plugin searchable
Domain Person.groovy --
package org.grails.twitter
class Person {
transient springSecurityService
String realName
String username
String password
boolean enabled
boolean accountExpired
boolean accountLocked
boolean passwordExpired
static hasMany = [followed:Person, status:Status]
static searchable = [only: 'realName']
static constraints = {
username blank: false, unique: true
password blank: false
}
static mapping = {
password column: '`password`'
}
Set<Authority> getAuthorities() {
PersonAuthority.findAllByPerson(this).collect { it.authority } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
view/searchable/index.gsp ---
<html>
<head>
<meta name="layout" content="main" />
<title>What Are You Doing?</title>
<g:javascript library="jquery" plugin="jquery" />
</head>
<body>
<h1>Search For People To Follow</h1>
<div class="searchForm">
<g:form controller="searchable">
<g:textField name="q" value=""/>
</g:form>
</div>
<h1>What Are You Doing?</h1>
<div class="updateStatusForm">
<g:formRemote onSuccess="document.getElementById('messageArea').value='';" url="[action: 'updateStatus']" update="messageLists" name="updateStatusForm">
<g:textArea name="message" value="" id="messageArea" /><br/>
<g:submitButton name="Update Status" />
</g:formRemote>
</div>
<div id="messageLists">
<g:render template="messages" collection="${messages}" var="message"/>
</div>
</body>
</html>
It works fine. Now My problem starts. Now I want to add this searchable in my Post domain also where user can search post items. I am doing like this ...
Domain Post.groovy --
package groovypublish
class Post {
static hasMany = [comments:Comment]
String title
String teaser
String content
Date lastUpdated
Boolean published = false
SortedSet comments
static searchable = [only: 'title']
static constraints = {
title(nullable:false, blank:false, length:1..50)
teaser(length:0..100)
content(nullable:false, blank:false)
lastUpdated(nullable:true)
published(nullable:false)
}
}
and here is form view
view/post/list.gsp --
------ some code -----
<g:form controller="searchable" class="navbar-search pull-left">
<g:textField name="q" value="" class="search-query" placeholder="Search Posts"/>
</g:form>
------ some code ------
Now when I try to search post by post title then it showing error. It overrides searchable action. How to solve this problem ?
You can implement your own search method using searchable, call a controller function from your search form and perform search in that:
Let say you have two search forms:
<g:form controller="postsController" action="postAction" class="navbar-search pull-left">
<g:textField name="q" value="" class="search-query" placeholder="Search Posts"/>
</g:form>
and
<g:form controller="searchable">
<g:textField name="q" value=""/>
</g:form>
then in the PostCOntroller you can have postAction method to perform search:
def postAction (Integer max) {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
params.sort = "id"
params.order = "desc"
if(params?.q){
def result = Post .search(params.q , order:"desc" )
return [searchResults: result.results, searchResultsCount: result.total, popup : params.popup?.toBoolean()]
}else{
[searchResults: Post .list(params), searchResultsCount: Post .count(), popup : params.popup?.toBoolean()]
}
and same you can have a different function for another search, if you use remote form then you need to have two different div's on the search page, and you can render the result page out there.
let say you have:
<g:formRemote name="postSearchForm" update="postSearchResultsDiv" url="[controller: 'post', action:'postAction' , params: [popup: false]]">
<label for="searchText">Search Post:</label>
<input name="q" type="text" id="searchText" class="input-medium search-query"/>
<input id="searchButton" type="submit" class="btn-info" value="Search"/>
</g:formRemote>
<div id="postSearchResultsDiv">--Your search result for the form will display here--</div>
This remote form will call postAction method in your controller, you can have postAction.gsp page on the controller's view folder and print the result out there.
and on your search page, postSearchResultsDiv will have the search result(postAction GSP page output)
I solved my own problem...
I have done like this ..
PostController ---
import org.compass.core.engine.SearchEngineQueryParseException
class PostController
{
def searchableService
def searchpost = {
if (!params.q?.trim()) {
return [:]
}
try {
return [searchResult: searchableService.search(params.q, params)]
} catch (SearchEngineQueryParseException ex) {
return [parseException: true]
}
render(view:'searchpost')
}
.......
}
Search form ---
<g:form controller="post" action="searchpost" class="navbar-search pull-left">
<g:textField name="q" value="" class="search-query" placeholder="Search Posts"/>
</g:form>
searchpost.gsp //for showing result
<html>
<head>
<r:require modules="bootstrap"/>
<meta name="layout" content="main"/>
</head>
<body>
<g:render template="/layouts/header" />
<div class="well">
<g:each var="post" in="${searchResult?.results}">
<div>
<h2>${post.title}</h2>
<p>${post.teaser}</p>
<p>Last Updated: ${post.lastUpdated}</p>
<g:link controller="post" action="view" id="${post.id}" class="btn btn-success">
View this post
</g:link>
<g:if test="${post.author == currentLoggedInUser }">
<g:link controller="post" action="edit" id="${post.id}" class="btn btn-danger">
Edit this post
</g:link>
<g:actionSubmit action="delete" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" class="btn btn-inverse" />
</g:if>
<g:form>
<g:hiddenField name="id" value="${post?.id}" />
</g:form>
</div>
</g:each>
</div>
</body>
</html>
And it works :)

Grails controllers

I have a form similar to this one in Grails:
Name: _____
Age: _____
Street: _____
Email: ____
|Submit|
How can i pass all the filled in information to a controller that will add me the records to the database? Im kinda new to Grails, and my problem is i dont understand how to "pass" and get things to the controllers.
class Person {
String name
Integer age
String street
String email
}
class PersonController {
def save = {
def personInstance = new Person(params)
personInstance.save(flush:true)
}
}
<g:form controller="person" action="save">
<g:textField name="name" />
<g:textField name="age" />
<g:textField name="street" />
<g:textField name="email" />
<g:submitButton name="save" value="Save" />
</g:form>
Also, if you have a domain, you can run
grails generate-all com.foo.Person
And all the code will be generated for you. Then you can see how it is done.

Resources