How to build an edit form for a list of strings in Grails? - grails

I have a Grails domain class with a list of strings in it, and I want to edit these strings. For the sake of simplicity let's assume that the list is fixed size. Here's what I have:
MyEntity.groovy:
class MyEntity {
String name
List variables = ['one', 'two', 'three']
static hasMany = [
variables: String,
]
}
_fields/myEntity/variables/_widget.gsp:
<g:textField name="variables[0]" value="${value[0]}" />
<g:textField name="variables[1]" value="${value[1]}" />
<g:textField name="variables[2]" value="${value[2]}" />
This renders text fields for each element in the list that are prefilled with the correct values. However, when I edit the values and sumbit the form my edits get discarded. What am I missing?

Ok, I found it myself. The input fields all need to have the name of the domain property, without any index:
<g:textField id="variables[0]" name="variables" value="${value[0]}" />
<g:textField id="variables[1]" name="variables" value="${value[1]}" />
<g:textField id="variables[2]" name="variables" value="${value[2]}" />

Related

displaying bean class items on view - beginner

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.

Submitting objects and lists struts1

I have a class MyClass as below
public class MyClass {
private int fieldOne; //with getter, setter
private String fieldTwo; //with getter, setter
}
I have following two fields in my form bean
private MyClass myObject; //with getter, setter
private ArraList<MyClass>myList; //with getter, setter
Using struts1 I want to submit object and list of objects from web-page form.
In struts2 we can get object and list in action as below (considering fields are not in action class instead of form bean). When following fields are submitted, struts2 initiates myObject and myList for me with submitted values. (Parameters Interceptor is the magician behind the scene in struts2.)
<!-- Object -->
<input type="text" name="myObject.fieldOne" value="1" />
<input type="text" name="myObject.fieldTwo" value="Two" />
...
<!-- List -->
<input type="text" name="myList[0].fieldOne" value="1" />
<input type="text" name="myList[0].fieldTwo" value="Two" />
<input type="text" name="myList[1].fieldOne" value="10" />
<input type="text" name="myList[1].fieldTwo" value="Twenty" />
Is there any way to perform such magic in struts1?
AFAIR, the same would work in Struts1, provided the list in your form bean contains a list which already has the right size. I.e. if the last input text has the name myList[7].fieldOne, the list should be of size 8 at least, and thus be prepopulated with 8 MyClass instances. STruts will only do formBean.getMyList().get(7).setFieldOne(10).
See http://struts.apache.org/development/1.x/struts-taglib/indexedprops.html for more details.

Saving Set of Domains For a Parent

I have the following Domains:
class Attribute {
static hasMany = [attributeParameters: AttributeParameter]
}
class AttributeParameter {
String value
Integer sequenceNo
static belongsTo = [attribute: Attribute]
}
I have a form where I want to display all the existing AttributeParameters for an Attribute and allow the user to populate their values and click Save. On Save, each AttributeParameter (which already has an ID) needs to be updated.
I'm currently drawing a blank on how I need to create the HTML for this to work. I've tried this:
Code simplified to clarity:
<form>
<input type="hidden" name="attributeParameters[0].id" value="1" />
<input type="text" name="attributeParameters[0].value" value="1234567" />
<input type="hidden" name="attributeParameters[1].id" value="2" />
<input type="text" name="attributeParameters[1].value" value="name" />
</form>
def save() {
def attribute = Attribute.get(params.id)
attribute.properties = params
}
and it populates the collection correctly, but it doesn't work because the AttributeParameter isn't being fetched before the save, so it is failing with an error:
A collection with cascade="all-delete-orphan" was no longer referenced
by the owning entity instance: com.foo.Attribute.attributeParameters
UPDATE:
I modified the HTML to the following:
<form>
<input type="hidden" name="attributeParameters.id" value="1" />
<input type="text" name="attributeParameters.value" value="1234567" />
<input type="hidden" name="attributeParameters.id" value="2" />
<input type="text" name="attributeParameters.value" value="name" />
</form>
And the controller:
params.list('attributeParameters').each {
def ap = AttributeParameter.get(it.id)
ap.value = it.value
ap.save()
}
This works. My only concern is the order in which the parameters come in. If they always come into the params object in the same order they show up on the form, then I should be ok. but if they ever come in differently, I could be modifying the value of the wrong AttributeParameter.
So still looking for a better way or some sort of verification that they params will always be first in-first out.
UPDATE 2:
I ran across this post and it is what I want but I cannot change Attribute.attributeParameters into a List. They need to stay as a Set.
Could you do something like this:
<form>
<input type="text" name="attributeParameter.1" value="1234567" />
<input type="text" name="attributeParameter.2" value="name" />
</form>
Where you create the names and values dynamically from each AttributeParameter:
<g:textField name="attributeParameter.${attributeParameterInstance.id}" value="${attributeParameterInstance.value}" />
And then in your controller
params.attributeParameter.each {id, val->
def ap = AttributeParameter.get(id)
ap.value = val
ap.save()
}
That way you have the actual id of each parameter directly and it wouldn't matter which order they were processed.

Grails <field type="number" ...> not working ...?

first post to this forum ...
The Grails 2.0.1 < field type="number" > doesn't seem to be working out of the box, but perhaps my usage is incorrect, so I'm looking here for a sanity check.
Here's the field in my domain entity:
Long locationId
static constraints = {
locationId(blank: false)
}
Here's the resulting field in the scaffolded-template generated _form.gsp:
<g:field type="number" name="locationId" required="" value="${fieldValue(bean: myEntityInstance, field: 'locationId')}"/>
But here's the result in the html, as per "view source":
<input type="number" name="locationId" required="" value="" id="locationId" />
And my problem is that the form blanks out the existing value of that field, as per: value="".
The other fields (all strings) are populated correctly.
Is the Grails 2.0.1 "number" gsp field working correctly for other people?
Regards
Rob
Try:
<g:field type="number" name="locationId" required="" value="${myEntityInstance.locationId}"/>
If you have any value of 4 or more figures like 1000, fieldValue tries to display it 1,000
Check the actual value of ${fieldValue(bean: myEntityInstance, field: 'locationId')}
Print it out
<%
System.out.println fieldValue(bean: myEntityInstance, field: 'locationId')
%>
i've not had a problem with the 'number' type, it works for me exactly as you have used it

Grails form data binding when another domain object is referenced in the form

How do I get Grails data binding to correctly bind referenced objects (such as Country in the example below)?
Given the following two Grails domain classes ..
class User {
String username
Country country
}
class Country {
String name
}
.. and the following HTML form ..
<g:form>
<g:textField name="user.username" value="${user.username}" />
<g:select name="user.country" from="${Country.list()}" optionKey="id" />
</g:form>
.. and the following code in the corresponding action ..
User user = new User(params["user"])
.. I would have hoped that user.username and user.country would get bind. However, it appears as if username.username gets bind, whereas user.country is not. What is the correct syntax to bind referenced objects (user.country in this example)?
The binding of the "country" property starts working if ..
<g:select name="user.country" from="${Country.list()}" optionKey="id" />
.. is changed to ..
<g:select name="user.country.id" from="${Country.list()}" optionKey="id" />
You should also look into command objects. They can validate and bind all of your parameters at once.

Resources