Read-only (print) version of JSP form using Spring 2.0.x and form tags? - spring

Is there a way to easily create a readonly version of JSP form in Spring?
i.e., I have a command object that's filled and if I show it as a form it works great, all the selects and radiobuttons get bound properly. However, my command object only holds id's of properties, not labels (i.e. and id from a select or a radiobutton list that gets bound on JSP load).
What I'd like to do is make a read only version where there'd be just a label - value list, without html objects such as inputs, selects and such.
So basically, in an edit version, there'd be something like
<form:select path="type.id" id="type">
<form:options items="${types}" itemLabel="name" itemValue="id"/>
</form:select>
but in the read only version I'd like to be able to automatically print only the exact type.name that got selected, i.e.
<c:out value="${commandName.type.name}"/>
Is there such a possibility, or do I have to mess with this in controller?

Ok so I guess there's no elegant way of matching IDs and values from model with IDs in command. Instead of doing extra work in controller, I matched the IDs on JSP, i.e.
<c:forEach var="type" items="${types}">
<c:if test="${type.id == commandName.type.id}">
<c:out value="${type.name}"/>
</c:if>
</c:forEach>
It's a bit extra work, but I'd rather do this than have a number of iterations over a List in my controller.

Related

Spring form:options is extremely slow in jsp

I have this slow code in my jsp:
<form:options itemLabel="name" itemValue="id" items="${view.users}" />
And when I just replace it with
<c:forEach items="${view.users}" var="user">
<form:option value="${user.id}">${user.name}
</form:option>
</c:forEach>
There is big impact on the performance. I just can understand why? Does this is because of view.users collection of complex objects?
As explained in the Spring documentation for the <options> tag,
The combined usage of an option tag with the options tag generates the same standard HTML, but allows you to explicitly specify a value in the JSP that is for display only (where it belongs) such as the default string in the example: "-- Please Select".
The items attribute is typically populated with a collection or array of item objects. itemValue and itemLabel simply refer to bean properties of those item objects, if specified; otherwise, the item objects themselves will be stringified. Alternatively, you may specify a Map of items, in which case the map keys are interpreted as option values and the map values correspond to option labels. If itemValue and/or itemLabel happen to be specified as well, the item value property will apply to the map key and the item label property will apply to the map value.
Here, Spring is checking for bean properties and before rendering to the actual HTML the type conversions are done. So, this makes a lot of background work to provide the clean code for the developers (which comes at the price of performance).
So, if there is no specific requirement/logic to display the options, prefer the basic HTML <option> tag.

Which View implementation handles JSPs in Spring MVC?

In the SpringMVC documentation I see this for AbstractView:
Direct Known Subclasses:
AbstractExcelView, AbstractFeedView,
AbstractJackson2View, AbstractJExcelView,
AbstractPdfView, AbstractUrlBasedView,
AbstractXlsView, MarshallingView
Which implementation handles regular JSP Views?
The reason for my question is that I want to extend SpringMVC's JSP View, to support a Read-Only mode for a form. The regular view would be the normal JSP, but a Read-Only View would be an extension of the JSP where all fields are converted to labels, i.e. they can't be modified.
Any advice on this approach appreciated.
What I understand is you need to get a JSF component root, iterate over all elements, find input fields and replace them with non-input - labels instead?
JSP does not 'like' modifying it's components at runtime. In JSF I could suggest you implement a TagHandler to modify the component tree based on some parameter returned in the View Model.
In your case - a simple solution would be to either disable inputs based on parameter value
<h:inputText value="${inputValue}" disabled="${formDisabled}" />
or render different inputs based on parameter value
<c:if test="${formDisabled}">
<div><h:outputText value="${inputValue}" />
</c:if>
<c:if test="${!formDisabled}">
<h:inputText value="${inputValue}" />
</c:if>

View component of MVC. Should I pre generate HTML tag elements in the Controller for the View?

I'am currently creating a MVC Java Web App with Struts2.
One element of my app is searching for some results via form. When the user submits the form an Action gets the necessary values from the database and populates a Map:
Map<Integer,List<String>> values = new HashMap<Integer,List<String>>();
Which has a list of column values for each row.
By Following this approach I can have generic JSP for displaying the results of any resultbox:
<s:div cssClass='resultContainer'
cssStyle=' min-height: 150px; max-height:%{header}px; overflow: auto; %{display}; '
theme="qxhtml">
<table id='resultTable'>
<tr id='tableHeader'>
<s:iterator value="headers">
<th><s:property /></th>
</s:iterator>
</tr>
<s:iterator value="values">
<tr class='results'>
<s:iterator value="value">
<td><s:property escape="false" /></td>
</s:iterator>
</tr>
</s:iterator>
</table>
I feel now that this is a bad approach. Instead I should change the Map to a List of ResultBoxRow objects. Each ResultBox will have its own View Jsp instead of one generic one allowing me to iterate over the objects and output for example:
<s:iterator value="value">
<td><s:property name="firstname" /></td>
<td><s:property name="lastname" /></td>
etc.
In the case of the table headers I may need to give certain headers individual style properties. I feel these should be defined in the JSP itself rather than get the JSP to reference a value from the controller containing the style for that header.
I think my overall question is how much should the controller control the style/display of elements of the View? I feel it should just generate the individual elements displayed in the tags but not the values to put in the "style" tag of the row for example. Even if this does sacrifice a simple single JSP to handle every result box.
It would be great to get your opinions.
The controller should have nothing to do with the display mechanism: that's the point of MVC, to completely separate the data from its presentation.
You can still DRY up the view layer via custom tags, includes, templates, etc. Styles may be passed as attributes, while the underlying DOM would be created by a single page or template.
It also matters what the nature of the attributes you want to pass. If they're semantic that could logically from from the model or controller that's fine. If they're purely presentational, like colors, widths, etc. then it has no business in the model or controller.

Spring MVC checkbox tag not posting changes made

I have trouble using spring mvc checkbox tag. I have a BookmarkMapping object which in turn has List object. Inside Folder Mapping there are three attributes like id, name and isMapped (boolean). It is this isMapped property based on which I intend to show the checkbox.
So in my page I get modelAttribute as 'bookmarkMapping'. inside which there is a list of folderMapping. Each of the item inside folderMapping is isMapped set as true or false for my checkbox checked attribute.
I am trying this
<c:forEach var="folderMapping" items="${bookmarkMapping.folderMapping}" varStatus="i">
<form:checkbox path="folderMapping[${i.count-1}].isMapped" label="${folderMapping.folderName}"/>
</c:forEach>
This displays the checkboxes fine in html but when posted it is nor reflecting changes of checkboxes as true /false in posted objects. It always shows false.
Set the value attribute of the checkbox tag.
<c:forEach var="folderMapping" items="${bookmarkMapping.folderMapping}" varStatus="i">
<form:checkbox path="folderMapping[${i.count-1}].isMapped"
value = "${folderMapping[${i.count-1}].isMapped}"
label="${folderMapping.folderName}"/>
</c:forEach>
Have you tried the <form:checkboxes /> tag? I think this is what you need here, maybe could solve your problem. Try something like this, replacing your <c:forEach /> tag:
<form:checkboxes path="folderMapping" items="${allCheckboxValues}" itemLabel="folderName" itemValue="isMapped"/>
You need to prepopulate allCheckboxValues in your controller with all possible values.
Check out spring documentation about this tag for more help and the TLD documentation.

How can I use Spring MVC "form" tag instead of my "input" tags?

What I have:
I have a generic JSP page that is used throughout my application for displaying certain entities. The code that I am interested in goes like this:
<form:form modelAttribute="object"/>
<core:forEach items="${sections}" var="section" varStatus="itemStat">
<core:forEach items="${section.fields}" var="fieldDef">
<form:input path="${fieldDef.fieldName}"/>
</core:forEach>
</core:forEach>
<form:form>
For each section, and for each field in that section, I have an input having the path fieldName, which is what I want to display from each field.
What I want:
I would like instead of the input to be a simple text, like a label.
What I have tried:
I am most certain that I can do it somehow with <form:label> but I can't really make it work. Making a <form:label path="${fieldDef.fieldName}" /> just tells the browser for which field I need the label, but doesn't get the actual value from it.
I have also tried something like ${object.fieldDef.fieldName}, but in order for this to work I would have to first analyze the value of ${fieldDef.fieldName}, which would give me the name of the column, and then do a ${object.column}, but column being a variable I haven't been able to make this work in any way.
Alternative:
An alternative would be to just make the inputs as disabled and remove the border with CSS, but that would be a dirty way and from what I saw it is also tricky for IE different versions. I am sure that I can handle it directly.
I am a little intrigued by the fact that <form:input path="..."> puts into the input what it finds corresponding to that path (same goes for other form elements), but with label it works different.
So, what I want is basically simple, but I haven't managed to find a way. If someone could shed some light, that would be great. Thanks in advance !
You could look into the spring bind tag. I haven't tried using it before but this may work for you, in place of the input tag
<spring:bind path="fieldDef.fieldName">
${status.value}
</spring:bind>
reference: http://static.springsource.org/spring/docs/1.1.5/taglib/tag/BindTag.html
Instead of
<form:input path="${fieldDef.fieldName}"/>
use
<c:out value="${fieldDef.fieldName}"/>
It would display whatever value is there instead of creating a input field. Hope this helps you. Cheers.
Using the spring form tab, one option would be to use
<form:input disabled="true" path="${fieldDef.fieldName}"/>
To further make it not look like an input you could use CSS to style it to your preference.
Some css styles you could use:
background-color:#EEEEEE;border: 0px solid;
Update:
You could look into the spring bind tag. I haven't tried using it before but this may work for you, in place of the input tag
<spring:bind path="fieldDef.fieldName">
${status.value}
</spring:bind>

Resources