Passing values to input through g:each iteration - grails

Say if i have this data from my controller that i want to pass it to my GSP
def test = [value: ['TEST1', 'TEST2', 'TEST3']]
And in my GSP, i have the following
<g:set var="counter" value="${0}"/>
<g:set var="count" value="${count}"/>
<g:while test="${counter < count}">
<g:set var="counter" value="${counter+1}"/>
<g:each var='obj' in='${test}' status='i'>
<g:textField id='justATest1' name='justATest' value='obj.value'>
<g:textField id='justATest2' name='justATest' value='obj.value'>
<g:textField id='justATest3' name='justATest' value='obj.value'>
</g:each>
</g:while>
And i want it so that justATest1 will get TEST1, justATest2 will get TEST2 and justATest3 will get TEST3.
How can i achieve that?

Assuming your model contains the following
def myAction() {
[value: ['TEST1', 'TEST2', 'TEST3']]
}
This should do it
<g:each status="i" in="${value}" var="item">
<g:textField id="justATest${i}" name='justATest' value="${item}">
</g:each>

Ok seems i managed to iterate object in GSP
<g:each var='obj' in='${test}'>
<g:each var='subObj' in='${obj.value}'>
<p>${subObj}</p>
</g:each>
</g:each>
But kind of not elegant enough.
I can do it too with this, as what Donal put in his answer
<g:each var='obj' in='${test.value}'>
<p>${obj}</p>
</g:each>
But it would be hard i think if i want to iterate each item inside test object separately and uniquely.
Anyone please feel free to fix my approach.

Related

How can I use g:render with my g:each variable from a Map collection?

I have a def statusMap = HashMap<String, List<MyItem>>() that gets passed into my gsp page.
In my gsp page I have the following:
<g:each var="myList" in="${statusMap}">
<div id="pending_list" class="onTop">
<g:render template="/list" model="['list':"${myList.value}", 'listSize':"${myList.value.size()}"]" />
</div>
</g:each>
But I can't seem to correctly pass myList.value and myList.value.size() into my template. I think my quotes are wrong somehow but I'm not sure.
How can I correctly pass myList.value and myList.value.size() into the list template through the model?
Since you are using a map your itteration is based on keys within that Map. So the basic syntax looks like this:
<g:each in=${yourCoolMap.entrySet()}" var="entry">
${entry.key} = ${entry.value}
</g:each>
Thus, your code will look something like this:
<g:each var="myList" in="${statusMap.entrySet()}">
<div id="pending_list" class="onTop">
<g:render template="/list" model="['list': myList.value, 'listSize': myList.value.size()]" />
</div>
</g:each>

IndexOutOfBoundsException when binding children

I have the following gsp in Grails 2.1.1 (simplified version):
<g:form ...>
<g:each in="${team.players}" var="player" status="i">
<g:hiddenField name="players[${i}].id" value="${player.id}" />
<g:textField name="players[${i}].name" value="${player.name}" />
<g:textField name="players[${i}].position" value="${player.position}" />
</g:each>
</g:form>
Given that the particular Team has 2 players, when I do the following in the controller I get java.lang.IndexOutOfBoundsException: Index: 1, Size: 1:
def teamInstance = Team.get(params.id)
teamInstance.properties = params // this is where IndexOutOfBoundsException happens
teamInstance.save()
Interestingly, when I remove players[${i}].id parameter the error goes away, but then the data for the two players is randomly swapped around because Grails doesn't know how to match the a player from the form to one in the players collection.
Anyone know what is going on here?
EDIT: Here is a sample app: https://github.com/zoran119/binding-test

Struts2 based quiz application using DB for getting questions and storing results

jsp file
<s:iterator value="questions" status="status">
<table border="3px" bgcolor="yellow">
<tr bgcolor="white" >
<td nowrap><s:property value="QuestionNumber"/></td>
<td nowrap><s:property value="Question"/></td>
</tr>
<tr>
<td nowrap><input type="radio" name="<s:property value="QuestionNumber"/>" value="1"/><s:property value="Option1"/></td>
<td nowrap><input type="radio" name="<s:property value="QuestionNumber"/>" value="2"/><s:property value="Option2"/></td>
</tr>
<tr>
<td nowrap><input type="radio" name="<s:property value="QuestionNumber"/>" value="3"/><s:property value="Option3"/></td>
<td nowrap><input type="radio" name="<s:property value="QuestionNumber"/>" value="4"/><s:property value="Option4"/></td>
</tr>
</table>
<s:hidden> </s:hidden>
</s:iterator>
<s:hidden id="answers" value="answers"/>
<s:submit name="submit" onclick="submitform()"/>
</s:form>
property values are being populated from DB using the Action class.
My problem is that i want to collect the list answers for a quiz and get it to the java classes for evaluation of score. Im not able to get any idea as how to do it
My DB has Questions table with the list of questions with options and correct answer.
I have a Question Bean Object.
You have an Action with a private List<Question> questions;, with Getter and Setter.
You populate your JSP reading the list from the Getter.
You can post that list back from the JSP to the Action's Setter by using OGNL for keeping informations on lines detail.
To do this, use Struts tags (<s:radio instead of <radio ) and set a name including the index of the line.
For example, with a textfield, instead of
<s:iterator value="questions" status="status">
<s:textfield name="question" />
</s:iterator>
use something like (untested, maybe some adjustments needed)
<s:iterator value="questions" status="status">
<s:textfield name="questions[%{#status.index}].question" />
</s:iterator>
Just adapt this for your radio case,
and in the Action you will receive your List fully populated.
(You can even validate a list posted like this usign Visitor validator: not your case, but it's worth knowing).
there are many ways to do this. the easiest way is to implement ParameterAware, checkout the link ParameterAware, then you can get all your parameters like this: (I'm assuming, QuestionNumber is a parameter of your bean question)
String param1 = parameters.get(question.getQuestionNumber);
you can put this line in a loop, so you can get all your parameters...

Grails: GSP variable substitution in g:each tag

I have a loop inside a loop and want to substitute the value of first var into second. Below is the code snippet.
<g:each in="${tables}" status="i" var="table">
<div class="tabletitle">
${table.name}
</div>
<table>
<thead>
<tr>
<g:each in="${${table.name}DisplayColumns}" status="k" var="displayColumn">
<td>${displayColumn}</td>
</g:each>
</tr>
</thead>
<tbody>
....
....
</tbody>
</table>
</g:each>
${table.name} substitution in second g:each tag is not working. Any idea to make it work?
Try this:
<g:each in="${evaluate(table.name+'DisplayColumns')}" status="k" var="displayColumn">
Interesting, I've never used evaluate inside a gsp, as Kelly suggests. But may I suggest a less optimal approach?
You can store ${table.name} inside a variable with <g:set> ( http://grails.org/doc/2.0.x/ref/Tags/set.html )
Do you know that you can pass any object to a GSP? Even maps (you're trying to emulate maps, I don't know why), and use it like:
<g:each in="${displayColumns[table.name]}">
where displayColumns is a Map that contains columns for each table.
Btw, more clean way, is to use special object, that includes this data. Something like TableDetails that have List<String> getColumns() method. So you can use
<g:each in="${tables}" var="table">
${table.name}
<g:each in="${table.columns}" var="column">
${column}
</g:each>
</g:each>

Grails iterating in gsp vs. accessing Map elements

Full context: I'm trying to process multiple files using a grails Application. The code I will display comes from the post-processing page where it gives information about the files processed.
My initial sense was to use code like this:
<table>
<tr>
<th>Parsed from Excel:</th>
<th>Uploaded to DS:</th>
<th>File Name:</th>
<th>Size:</th>
</tr>
<tr>
<g:each in="${fileContents}" var="item">
<td>${item}</td>
</g:each>
<%--
<td>${fileContents.ExcelRows?.encodeAsHTML()}</td>
<td>${fileContents.policies?.encodeAsHTML()}</td>
<td>${fileContents.originalFileName?.encodeAsHTML()}</td>
<td>${fileContents.Size?.encodeAsHTML()}</td>
--%>
</tr>
</table>
Now, what I don't understand is why the contents displayed in the <g:each loop always reports key=value such as ExcelRows=14 as I have received in one output case.
When I switch comments (note the <%-- tag being used) it works exactly as expected. From my "ExcelRows" column, I get just "14." What is wrong with my thinking that the <g:each loop should do the same thing? Intuitively it comes down to For each item in fileContents
display item.
My controller code:
def processFile = {
def uploadedFile = request.getFile('excelFile')
//...snipped
def fileContents = [
ExcelRows:"${ods.numberOfRows}",
policies:"${ods.numberOfPolicies}",
originalFileName: "${ods.originalFilename}",
Size:"${ods.size}"
]
[fileContents:fileContents]
}
When iterating over a map you'll be working with Entrys. Try using:
<g:each in="${fileContents}" var="item">
<td>${item.value?.encodeAsHTML()}</td>
</g:each>
Or
<g:each in="${fileContents.values()}" var="item">
<td>${item?.encodeAsHTML()}</td>
</g:each>

Resources