I display rows in an HTML table with a checkbox in a column in each row of the table something like the following.
<s:iterator value="objects" status="loopStatus">
<td>
<s:label for="%{id}" value="%{#loopStatus.index+1}"/>
<s:checkbox id="%{id}" name="chk" fieldValue="%{id}" value="false"/>
</td>
<!--Other columns-->
</s:iterator>
objects is is a list of objects of a JPA entity, List<Entity> initialized in an action class. id is a value of type Long that corresponds to a primary key column in the database.
The values of these checkboxes are set to its corresponding property in an action class, when the form is submitted.
private List<Long>chk;
//setters & getters.
The values of selected checkboxes are correctly set to this property chk. This list of values is then used to delete rows from the database.
This works just fine. A problem occurs, when there is only one row in the table. In which case, an unnecessary conversion error occurs, while performing operations other than deletion (like updating/inserting a row) which requires this checkbox to be selected which is quite unnecessary and should happen only while performing deletion.
Invalid field value for field "chk".
If I deliberately add an extra checkbox with the same name chk then, this conversion error disappears.
Presumably it appears that a single checkbox is not correctly mapped to a list of values of type Long, List<Long>.
What is the way to get rid of this error, when there is only a single row to be displayed in an HTML table?
If you don't check a single checkbox it value by default is set to false. You can set the default in checkbox interceptor uncheckedValue property.
Additionally you may consider to add hidden field so that checkbox interceptor will think there are multiple chekboxes when there is only one and won't add default value.
For your checkbox the hidden field name will be __checkbox_chk.
<s:hidden name="__checkbox_chk"/>
Try this one which explicitly cites the array index:
<s:iterator value="objects" status="loopStatus">
<td>
<s:label for="%{id}" value="%{#loopStatus.index+1}"/>
<s:checkbox id="%{id}" name="chk[%{#loopStatus.count}]" fieldValue="%{id}" value="false"/>
</td>
<!--Other columns-->
</s:iterator>
Related
I have an issue while updating the render on a select field with Tapestry.
I want to disable 2 fields (1 textfield and 1 select field) depending of what I selected in another field (also a select field). I want to render the disabled fields immediately so I am using the Tapestry Zone system to do so.
However I keep getting the following exception for the select field when I select an item from the "fruitOrVegetableSelect" list :
Parameter 'model' of component fruit/Edit:fruitNames is bound to null. This parameter is not allowed to be null.
Here is my code in the tml page :
<t:zone t:id="fruitsForEveryOneZone" update="show">
<tr>
<td> <t:select
t:id="fruitName" t:model="fruitNames"
value="fruit?.fruitName"
disabled="getDisabledFruitField()" />
</td>
<td><t:textfield t:id="numberOfFruits"
value="fruit?.quantity"
disabled="getDisabledFruitField()" />
</td>
</tr>
</t:zone>
And here is the code in the controller :
#OnEvent(component = "fruitOrVegetableSelect", value = EventConstants.VALUE_CHANGED)
public Object updateFruitOrVegetable(Plant plant)
{
if (plant.getName().equals("Fruit"){
this.disabledFruitField=false;
else {
this.disabledFruitField=true;
}
return new MultiZoneUpdate("fruitsForEveryOneZone", fruitsForEveryOneZone.getBody());
}
If I limit the zone so it only takes the textfield input it works fine (except that my select is never disabled). For some reason the "model" from my select field is lost in the process. Any idea why this happens and how I can avoid this problem?
This code is not showing how "fruitNames" is declared in java class. I guess that "fruitNames" is a variable and it's just lost. You should annotate "fruitNames" with #Persist and this should do the trick or declare "fruitNames" as a method (getFruitNames()).
I'm new to the front end side of Java EE and HTML5. I have read that you could use the data attribute to read through the DOM. How would you properly use this to get a session attribute already set by java. Compared to the other methods such as using a hidden input.
<input id="sid" type="hidden" name="series" value="${sessionScope.series} />
var sid = document.getElementById("sid"), series;
Use something like this:
<div id="div1" data-special-value="${sessionScope.series}"></div>
And get the attribute value like:
document.getElementById("div1").getAttribute("data-special-value")
Or even ( http://caniuse.com/dataset ):
document.getElementById("div1").dataset("special-value")
Or with jQuery:
$("#div1").attr("data-special-value")
// or
$("#div1").data("special-value")
Although I'm not sure storing a session value on an element is right. It's definitely not wrong, I'm just wondering what you'd need/use it for with sessions. Sessions appear once.
The data-* attributes are more useful with storing related data to something. For example, if you loop through a bunch of database records and print their columns, but want to also store the row's database id once, you'd use:
<c:forEach items="${rows}" var="row">
<tr data-row-id="${row.id}">
<td>${row.name}</td>
<td>${row.description}</td>
</tr>
</c:forEach>
Then if you want to get the original row.id value, it's stored in one place an encompasses everything it pertains to (the columns). This is usually how/where I use data-* attributes. Of course, there are many ideas/uses for this.
I got a row in my create.jspx as follows:
<field:select field="groupsowdrefs"
id="c_com_usergroups_manager_domain_Users_groupsowdrefs"
itemValue="id" items="${groupsviews}" multiple="true"
path="/groupsviews" z="yuLSgZ+z3Zrwet6KAYzGT+xFndc="/>
this field displays a box with rows populated by the relationship #ManyToMany between 2 entities.
Now the problem is that the first entity has only one String attribute which populates this box, but has itself a #ManytoOne relation with another entity. This value is important and is not shown in the box rows!
This happens because the field:select shows only attributes and not fields of related entities.
I tried to put an ItemLabel tag and it works but box rows show only one field at time.
Maybe a simple div which shows the info i need on clicking the rows of the box, or a concatenate ItemLabel, a jquery trick..or anything..would solve this, but jspx is hard to understand to me.
A possible solution would be to add a getter to the class you want, as a read-only property:
public getSelectDescription() {
// concatenate desired values
}
and use that property in the itemLabel
itemLabel="selectDescription"
I have a table with many rows, and each row has a link to a modal dialog box using struts2-jquery. I need to set a unique ID for each dialog in order to set this up, but I've tried multiple options without luck.
<s:iterator value="myBeanList" var="rrSum" status="status">
<tr>
<td>
<s:url id="ajax%{status.index}" action="smoRiskRegister" var="ajaxURL">
<s:param name="requestRiskID"><s:property value="#rrSum.rid" /></s:param>
</s:url>
<sj:dialog id="dialog3" href="%{ajaxURL}" title="Testing" />
<sj:a openDialog="dialog3"><s:property value="#rrSum.rid" /></sj:a>
</td>
</tr>
</s:iterator>
So instead of "dialog3" I want something like dialog%{status.index}. I can set the ID to this... but how do I reference it in the anchor tag? Unfortunately there is no var parameter for dialog :(
Just use %{#status.index} in anchor tag as well.
<sj:dialog id="dialog%{#status.index}" href="%{ajaxURL}" title="Testing" />
<sj:a openDialog="dialog%{#status.index}"><s:property value="#rrSum.rid" /></sj:a>
Note # sign, one have to use it when accessed object is not in the OGNL root.
The Action instance is always pushed onto the value stack. Because the Action is on the stack, and the stack is the OGNL root, references to Action properties can omit the # marker. But, to access other objects in the ActionContext, we must use the # notation so OGNL knows not to look in the root object, but for some other object in the ActionContext.
Read about OGNL in Struts2: http://struts.apache.org/2.x/docs/ognl.html.
I'm using Struts2 to display the contents of a list of objects on a JSP.
The flow of events is as following:
GetDataAction.java -> fetches values from
the database, fills in the ArrayList
named tableList. On success, the
displayData.jsp is shown.
displayData.jsp -> uses the s:iterate tag to display the values of objects
in the tableList.
The user changes some values in the
displayData.jsp and presses on the
Update button. On the click of
Update button, the
UpdateDataAction.java is called.
Now my problem is; How do I use the same tableList in UpdateDataAction.java to get the modified values?
I tried declaring an ArrayList with the same name 'tableList' (along with getters and setters), in UpdateDataAction.java but it throws a NullPointerException.
Please suggest.
IMO the way you are updating is not a good idea.Either you should link every row to a seperate edit page or use ajax.There are many plugins available to update table values using ajax,If you need i can provide you the links
Back to your way of doing it,i guess you are doing it as follows
<s:form action="UpdateDataActionName">
<s:iterator value="tableList">
<s:textfield name="objectName.propertyName1" value="%(propertyName1)">
<s:textfield name="objectName.propertyName2" value="%(propertyName2)">
<s:textfield name="objectName.propertyName3" value="%(propertyName3)">
</s:iterator>
<s:submit value="Update"/>
</s:form>
Now declare a list in your UpdateDataAction,of type <objectNameoftableListType> i.e. the same object type which the tabeList is representing.The name of the list must be objectName.Try to Iteate and check if you are getting the right values as submitted from the jsp.