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"
Related
I'm working on a website in which users can add and edit things (it's not relevant describing what these things are in particular).
I'm implementing it using Thymeleaf for the frontend, Spring MVC for the backend and JPA for the database logic. Now I'm trying to implement the edit logic but I don't know which is the best way to do it.
What I'm thinking is: display to the user all the input fields (on a HTML page) that he is allowed to edit, already filled in with the current values. He can edit then whatever fields he wants and finally press the edit button to persist the changes.
Once I get the new object in the backend, I retrieve the old version from the database in order to check which field the user changed. For every field that got changed I update the old version and only when I've finished I call the JPA method save and I persist the new version of that object.
Is there a better way to do it?
It would be perfect if the object I put inside the model in order to display all its field to the user inside the HTML page, could mantain all the information of the old object and not just the ones the user can change. Let me explain better what I'm trying to say with an example:
Let's say the object we are trying to edit its called Person and has these attributes:
id
name
surname
money
nickname
sex
But the user can edit only the following attributes:
money
nickname
sex
so the controller which handler the get request of the page would look like this:
#GetMapping("person/{personId}/edit")
public String getEditPersonPage(#PathVariable Integer personId, Model model) {
Person person = personService.getById(personId); //person has all the attributes filled in
model.addAttribute("person", person);
and the controller which handler the put request looks like this:
#PutMapping("person/{personId}/edit")
public String editPerson(#ModelAttribute Person person, #PathVariable Integer personId){
personService.editPerson(person); //person has only the three fields filled in and all the other attributes as NULL
return "redirect:/person/" + personId;
}
the HTML page:
<form th:object="${person}" th:method="PUT">
<fieldset>
<p th:text="*{id}"></p>
<p th:text="*{name}"></p>
<p th:text="*{surname}"></p>
<input type="number" th:field="*{money}" th:value="*{money}" />
<input type="text" th:field="*{nickname}" th:value="*{nickname}" />
<input type="text" th:field="*{sex}" th:value="*{sex}" />
<input type="submit" value="Edit" />
</fieldset>
</form>
When I insert the object person inside the model to render the HTML page the object has all the attributes. Indeed I can decide which of its attributes display inside the HTML page (in this case only three: money, nickname and sex). But when the user press the submit button (edit), I receive only the fields displayed inside the HTML page (money, nickname, sex). So what I have to do is: I have to take these three fields, check if they are changed and if so, update the old version.
It would be perfect if when the user press the submit button, all the fields of person (and not just those three he is allowed to update) could be retrieved by the controller. In that case I could skip the check phase and persist directly the new version inside the database (with the old values unchanged and not set to NULL).
Any thoughts?
You can use readonly attributes for the ones that are not going to be edited.
I think is the best way in order to keep all the values visible in the form to give all the info to the user that is editing. All the values will be submitted and serialized with your object, but the form just allows to edit the three of them that you need.
A readonly element is just not editable, but gets sent when the according form submits. A disabled element isn't editable and isn't sent on submit.
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>
I am Having Struts 1.2 bean as below which contains Locations in Array
Register.java
public class Register extends ActionForm
{
private String[] userLocation = {"Chennai", "Bangalore", "Delhi", "Singapore"};
.
.
//Getters and Setters
.
.
.
}
I want to populate this in Dropdown select in options.I tried the Following code but it ain't working.Any Idea how to do this.Is it possible to do this with out using collection by using array.
RegisterForm.jsp
<html:select property="userSelectedLocation">
<html:options property="id" labelProperty="name" />
</html:select>
Read the documentation of the select tag and of the options tag.
The select tag expects to find the selected value of the select box in a property. You gave it userSelectedLocation as the property, but the action form doesn't seem to have any getUserSelectedLocation() method.
The options tag gets options from a collection of values. The place where it gets the collection depends on three attributes: collection, name and property. The documentation says:
Only property is specified - The value of this attribute is the name of a property of the ActionForm bean associated with our form, which will return the collection.
This means that the options tag looks for a method getId() in the action form that would return the array of values. It doesn't seem you have such a method.
The documentation clearly explains how the tag works. If you told us what you want to do (what do you want the select options to have as value and as labels, what is the property that contains the selected value), we could tell you what to use.
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.
I use a display table on a formBean :
<display:table name="${TableReferentielleFormBean.listeTableReferentielle}"
id="listeTableReferentielle" pagesize="${nb}" width="100%" class="table-separateur"
requestURI="${requestURI}" >
When I click on a column header on a paginated table, my result is a well sorted list in the table on first page. but the sort is lost when I click on another page of my table. Is there a configuration for display tag in order to keep this sorting criteria? Everything is managed by display tag with its request parameters (d-xxx-s etc.) and nothing in my servlet (requestURI value).
I 've already the displaytag.properties customized with the sort.amount = list value and I'm sure that this properties file is taken into account (I change another property to test it).
Try setting sort="list" right in your display:table declaration.