Spring MVC 3 - custom labels in <form:select> - forms

I'm creating a form in which user will be able to choose (among the others) the factory of a product.
Each factory is identified by and ID and has specific address.
I want to use custom label in following code:
<form:select items="${factories}" path="factory" itemValue="id" itemLabel="..."/>
At first i tried using Spring Formatter functionality (org.springframework.format.Formatter interface), but when I did this, and when I removed "itemLabel" attribute to have it displayed automatically via Formatter):
<form:select items="${factories}" path="factory" itemValue="id"/>
But then It wasn't selecting proper value if it was set (in case of editing).
Then I tried to:
<form:select path="factory" itemValue="id">
<c:forEach ...>
<form:option value="${factory.id}" label="${factory.address.city} ${factory.address.street}"
</c:foreach>
</form:select>
But as in earlier solution spring was not selecting proper value that was set in model.
My question is:
Is it possible to format entity in a way, that form:select works properly, when a value of select field is not the same as its label.

I had the same problem, the trouble is the form:option value and label maps directly to a property rather than having the flexibility to specify jstl.
So you have to hand crank the html, to something like:
<select name="factory">
<c:forEach var="factory" items="${factories}" >
<option value="${factory.id}" label="${factory.address.city} ${factory.address.street}"/>
</c:forEach>
</select>
Spring will pick up the 'path' based on the name attribute('factory' in this case), as it will try and map to the model object you are using automatically.
Another way is to add another field to the model to concatenate and format label as you wish. And if its an #Entity object then make the field #Transient.

You can also override toString() method in Factory class
#Override
public String toString() {
return "desired string";
}
Then in your jsp
<form:select items="${factories}" itemValue="id" path="factory"/>

Related

How do I replace an attribute value for attribute with multiple values in Wicket?

My class attribute has two CSS class values. The HTML starts out like this:
<input type="button" wicket:id="rowButton" class="jelly-button greenGradient"/>
And I want to dynamically change it to this:
<input type="button" wicket:id="rowButton" class="jelly-button redGradient"/>
Currently I am doing this:
component.add(new SimpleAttributeModifier("class", "jelly-button redGradient"));
What is the best way to do this in Wicket? There must be a more 'proper' way to do this than what I have done above.
Instead of using an attribute modifier with fixed text you could use an attribute appender with the text retrieved from a model. To change the class, just change the model's value. For example:
Model<String> gradientModel = new Model<String>("greenGradient");
...
component.add(AttributeModifier.append("class", gradientModel));
in the markup just have
<input type="button" wicket:id="rowButton" class="jelly-button"/>
Then when it is time to change the gradient use
gradientModel.setObject("redGradient");
or
gradientModel.setObject("greenGradient");
The example in the javadoc below explains it well
http://www.jarvana.com/jarvana/view/org/apache/wicket/wicket-core/1.5.2/wicket-core-1.5.2-javadoc.jar!/org/apache/wicket/behavior/AttributeAppender.html

struts2: param tag doesn't use conversion

Problem
In my struts2 application I have JSP page where the list of book is displayed. Each book has an id and the name. Also I want to place a link "edit" alongside any book, which can be edited by current user. This "edit" link should invoke corresponding action, passing book id as parameter to it. So I implemented this page using the code:
<table>
<s:iterator value="books" status="stat">
<tr>
<td><s:property value="id"/></td>
<td><s:property value="name"/></td>
<td>
<s:if test="canEdit[#stat.index]">
<s:a action="editBook">edit
<s:param name="bookId" value="id"/>
</s:a>
</s:if>
</td>
</tr>
</s:iterator>
</table>
Book id is not of a basic type, I use custom class for it. So I decided to implement my own converter.
And here comes the problem: in the code above converter is used only when evaluating tag <s:property value="id"/> but it is not used to evaluate <s:param name="bookId" value="id"/>. Instead toString() method of book id class is used. Why <s:param> doesn't use my converter? How do i force it to do so? Or maybe there is another way to pass book id as parameter in link?
Some (probably useless) details
To configure converter I placed xwork-conversion.properties inside my /src/main/resources/ folder with the following contents:
my.app.Id = my.app.struts.IdConverter
my.app.Id is an abstract class which is extended by book id class.
The result of rendering of the JSP for a single-entry list is the following:
<table>
<tr>
<td>8</td>
<td>Book 01</td>
<td>edit</td>
</tr>
</table>
id%288%29 is an escaped version of string id(8) which is the result of toString() method (defined in base abstract class my.app.Id) for id with int value of 8.
The <s:param> tag is meant for "simple" parameters. In this case, you may be able to just set a temporary value using <s:property> if that does the conversion you expect.
It uses the toString of the book id because that's what a getId() will print out when rendered, just as if you did a System.out.println(book.getId()).
Found corresponding issue with explanation of problem:
http://jira.opensymphony.com/browse/WW-808
In a few words the difference is between specifying <param value="myValue"/> and specifying <param><property value="myValue"/></param>. Conversion is used only in second case.

Spring #ModelAttribute doesn't care about commandName

JSP:
<form:form commandName="editWeather" method="post" action="../edit">
<!-- Input fields -->
<input type="submit" value="Submit">
</form:form>
And this is how I get the model in Spring:
#ModelAttribute("DONTGIVEADAMN") Weather weather
And I can still use the weather to do my operations and it works great, for example:
weatherService.editWeather(weather);
My question is...Why does this work?
Model attribute name doesn't matter when binding data received from a form (because names of form fields correspond to the names of fields of the model object), it matters only when rendering a form.
I particular, when model attribute name in your POST handler method doesn't match the commandName in the form, you will be able to receive the data, but won't be able to redisplay a form with validation errors.
its matching the class type (or interface), not the name of the variable/parameter; and the specified request mapping/method signature must be correct.

Passing Complex object from View to Controller: one object is always null

I'm passing a complex object as a Model to the View as
but when I get the Model back from the View, one particular object comes always null while other complex types are normally passed through
my View is the default Edit Strongly Typed View
What am I missing?
The ModelState Error says
The parameter conversion from type 'System.String' to type 'Julekalender.Database.CalendarInfo' failed because no type converter can convert between these types.
Why don't I get the same for the other types? How is it automatically converted?
I have added 3 fields (as the T4 template does not append this types) but I still get null when POSTing
The green boxed below is the field
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Calendar.Guid)%>
</div>
Even renaming the Action to
[HttpPost]
public ActionResult General2(GeneralInfo model)
gives the same error
Make sure that when you use this wizard there are input fields generated in the view for each property of the Calendar object so that when you post the form they will be sent to the controller action. I am not sure this is the case (haven't verified if the wizard does it for complex objects, I've never used this wizard).
In the resulting HTML you should have:
<input type="text" name="Calendar.Prop1" value="prop1 value" />
<input type="text" name="Calendar.Prop2" value="prop2 value" />
... and so on for each property you expect to get back in the post action
... of course those could be hidden fields if you don't want them to be editable
UPDATE:
The problem comes from the fact that you have a string variable called calendar in your action method and an object which has a property called Calendar which is confusing. Try renaming it:
[HttpPost]
public ActionResult General2(string calendarModel, GeneralInfo model)
Also don't forget to rename it in your view.

ASP.NET MVC 2: What Model property datatype will autobind an html select (DDL) with multiple selections?

The customer has a Model property that requires a comma separated list of selected options. We present their select list (DDL) as a multi-choice drop down.
What would the property datatype look like that would autobind multi-selections in the client side HTML select (DDL)?
The select posts data like this:
myOptions=Volvo&myOptions=Mercedes&myOptions=Audi
And we want to automagically bind it back to some property:
IList<string> CarChoices {get;set;}
So the POST action method parameter would be (Carform myForm)
which would have myForm.CarChoices which includes a List of the three selected cars?
I might be misunderstanding what you're trying to accomplish but I think this post from Phil Haack describes how to do what you're attempting to do in a clean way: http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Sometimes it is just easier to get your hands dirty and work with the HTML. I suggest doing something like this:
<select multiple>
<% foreach(var item in Model){ %>
<option value="<%= item.ID %>"><%= item.Description %></option>
<% } %>
</select>
obviously your model is your collection. You can also use the ViewData["Whatever"] object to pass data as well, your choice.