Spring form:options is extremely slow in jsp - spring

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.

Related

Kendo Bind Visible to Opposite of Value

I believe I already know the answer to this, but in kendo are you able to bind a DOM element's visibility to the opposite of if a value in the observable is null or false?
For example: the normal behavior is to show a <div> that has content the user needs to manipulate as part of a "step". I want to give the user the option to skip this step. To do this, I add a checkbox that says "skip" and in it I bind its value to the property IsSkip:
<input id="checkbox-allow-skip" type="checkbox" data-bind="value: IsSkip" />
Can I then bind the <div>'s visibility to the opposite of IsSkip like this (pseudo code for data-bind):
<div id="optional-step" data-bind="visible: !IsSkip">
<!-- ... -->
</div>
Edit - I believe that it may be worth noting that currently I'm generating the onchange event of the checkbox and setting the value of a new property named CannotSkip to the opposite of IsSkip and binding the visibility to CannotSkip.
As you're probably already aware, you can't invert the value of the property within your binding expression as per your pseudo code due to the way the binding is constructed. However, the visible reference which appears in the binding expression is not a reference to a DOM attribute, it's actually a reference to a kendo binder which has a counterpart, the invisible binder which inverts the value for you. Hence the simplest solution to your problem is just this:
<div id="optional-step" data-bind="invisible: IsSkip">
<!-- ... -->
</div>
Eventually however, you're sure to encounter a situation where this won't solve the problem for you e.g. perhaps the visibility depends on the state of several flags? This type of scenario is best handled by binding to a function instead where you can execute whatever logic is necessary. The most important thing to remember when you use this approach is to manipulate any properties of your view-model using the get and set methods of the observable object. This ensures that any bindings to your function will be refreshed when any of those properties change; in kendo parlance this is known as a dependent method. You could solve your problem using this approach, like so:
var viewModel = kendo.observable({
IsSkip: false,
CannotSkip: function() {
return !this.get("IsSkip");
}
});
<div id="optional-step" data-bind="visible: CannotSkip">
<!-- ... -->
</div>

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>

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>

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

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.

Resources