Is it possible to bind a form element to a List<Long>?
ie. <form:input path="formValues[0]" /> binding to an element in List<Long> formValues; in the form backing object?
When I try this, it fails because Long does not have a default constructor new Long().
I've worked around it by creating a dummy holder class
class DummyLong {
private Long value;
...
}
making the list in the formbacking object a List<DummyLong> and changing the form tag to <form:input path="formValues[0].value" /> but this seems unnecessarily hideous and I'm sure there must be a better way. Haven't been able to find it though.
Use List<Long> formValues with <form:input path="formValues" />
Related
I will like to edit a list of items in the same page. Each item should be edited using a separate form. I am creating a h:form within ui:repeat. Only when the last form is submitted, the user input is applied to the managed bean. For all other forms, user input is not applied to the model.
#ManagedBean
public class Controller {
Logger logger = Logger.getLogger("TestWeb");
private List<Customer> customerList;
public List<Customer> getCustomerList() {
if (customerList == null) {
customerList = new ArrayList<Customer>();
customerList.add(new Customer("Daffy Duck", "daffy#example.com"));
customerList.add(new Customer("Bugs Bunny", "bugs#example.com"));
customerList.add(new Customer("Samity Sam", "sam#example.com"));
}
return customerList;
}
public String updateCustomer(Customer c) {
logger.info("Updating: " + c.getName());
return null;
}
}
In the view, I have
<ui:repeat var="c" value="#{controller.customerList}">
<h:form>
<h3>Edit Customer</h3>
Name: <h:inputText value="#{c.name}"/><br/>
E-mail: <h:inputText value="#{c.email}"/><br/>
<h:commandButton value="Update"
action="#{controller.updateCustomer(c)}"/>
</h:form>
</ui:repeat>
I search for hours without any solution. What will be the correct way to do this? I can hack it by using a single form and using a ui:repeat within it. But there are many issues with that and I will rather not take that route. Thanks.
This is a bug in state saving of <ui:repeat> in Mojarra. There are several similar issue reports at http://java.net/jira/browse/JAVASERVERFACES, among others issue 2243.
You have basically 2 options: use another iterating component (e.g. <c:forEach>, <h:dataTable>, <t:dataList>, <p:dataList>, etc), or replace Mojarra by MyFaces (the <ui:repeat> in this construct works properly in there).
I'm trying to do a CRUD for my bean in Spring MVC and i found it to be a bit overwhelming.
thing is, that one of bean element is ArrayList of another class
its looks like
class Bean{
...
String componentName;
ArrayList<InnerComponent> component;
...
}
With getters and setters ofc
and InnerComponent is pritty simple, its like
class InnerComponent{
String key;
String va;
}
now Question: How can i create form, that allows to input something in that array list?
<form:form commandName="Bean" id="Bean" action="#">
<form:input type="text" path="componentName" /><br />
....??
<form:button>Submit</form:button>
</form:form>
Can figure this out...
you need to use CustomPropertyEditors for such.
1) here is thread having same question.
2) here is stackoverflow link.
3) here is Spring 3 reference doc link of propertyEditors chapter.
What is the best way to change data of, for example, User?
I got lots of properties like 'username', 'city', 'phone' and when I want to edit just one field ('password'), I have to do this:
<form:form action="editUser.htm?id=${user.id}" commandname="user">
<form:hidden path='username' />
<form:hidden path='city' />
<form:hidden path='phone' />
<form:input path='password' />
....
In my controller action is defined:
#RequestMapping(value = "/editUser.htm", method=RequestMethod.POST)
public ModelAndView ordertypeedit(#ModelAttribute("user") User user,
BindingResult result, HttpServletRequest request)throws Exception{
userTypeValidator.validate(orderType, result);
if(result.hasErrors()){
(...)
return new ModelAndView(...);
}
orderTypeDAO.update(orderType);
return new ModelAndView(...);
I don't like to set all the to my action form... If I miss it, it shows error 'column 'username' cannot be null".
It depends if your properties are validated or mandatory on that form:
If not, then you don't need to submit them with your form:
<form:form action="editUser.htm?id=${user.id}" commandname="user">
<form:input path='password' />
and in your controller you will get user object with only user parameter.
Alternative way is to pass regular (not Spring MVC) form and create inside user object with only id and password properties.
you can use simple (without spring tags) form with one input and get it in controller using #RequestParam
I'm dynamically adding textboxes to a form on my jsp page using Javascript. When that form is submitted to an action, how does my action get the values of those textboxes? (I'm using Struts 2, btw.) In ASP.NET, I was able to find them in Form.Request/FormCollection. Is there a Struts 2 equivalent? Thanks a million.
In Struts2, you create beans in the form to do submit values. In order to create the input text-box, use the <s> tag. For example :
<s:textfield name="loginBean.userName" label="UserName" required="true" />
Here loginBean is the bean passed to the jsp page when.
Bean consists of variable declarations and getters-setters for the variable.
Then in the back-end Java where the form is submitted to, you can access the same bean.
Declare getter-setter in Java and then you can access the properties of the bean.
public LoginBean getLoginBean() {
return loginBean;
}
public void setLoginBean(LoginBean loginBean) {
this.loginBean = loginBean;
}
public String authenticate() {
String username = loginBean.getUserName();
I would recommend looking at source codes of open-source Struts projects.
It sounds like you're trying to populate a dynamic list. To do that, you just have to use the [n] index syntax at the end of your Action class property name:
HTML:
<input type="text" name="yourCollection[0]" value="first value" />
<input type="text" name="yourCollection[1]" value="second value" />
<input type="text" name="yourCollection[2]" value="third value" />
Action Class:
public class YourAction extends Action {
public List<String> yourCollection;
public List<String> getYourCollection(){
return yourCollection;
}
public void setYourCollection(List<String> aCollection){
this.yourCollection = aCollection;
}
}
In my interface I have a list of text boxes, something like this :
http://screencast.com/t/YjIxNjUyNmU
The number of textboxes is unknown as each of them is associated with a Template.
In my page, the goal is to associate a number to some of those templates.
Here is a sample HTML code :
<% // loop on the templates
foreach(ITemplate template in templates)
{
// get the content from the input dictionary
int val;
content.TryGetValue(template.Id, out val);
// convert it as a string
string value = ((val > 0) ? val.ToString() : string.Empty);
// compute the element name/id (for dictionary binding)
string id = ??????????
string name = ??????????????
%>
<label for="<%= name %>"><%= template.Name %></label>
<input type="text" id="<%= id %>" name="<%= name %>" value="<%= value %>" />
<br />
<% }
%>
What I expect, in my controller, is to get a IDictionary where the first int is the template ID , and the other is the count given by the user.
Here is what I want :
public ActionResult Save(int? id, Dictionary<int, int> countByTemplate)
I tried a lot of things but nothing worked. I tried to read the sources but it's a maze, and I'm getting a headhache trying to get information about model binding.
Questions :
is there a good ressource on how the modelbinding works ?
I'd like someting exhaustive, I'm tired of the 84093043 blogs that talk about a given specific example.
how can I build my HTML, using to get a IDictionary (or even a IDictionary in my controller's action ?
Thanks a lot for your help
Information on how to write your input elements for binding to arrays, dictionaries, and other collections can be found at http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx.
Ok... Thanks to Levi I was able to get on a solution.
Not the cleaner one, but it works.
The HTML should be written this way:
<%
int counter = 0;
// loop on the templates
foreach(ITemplate template in templates)
{
// get the value as text
int val;
content.TryGetValue(template.Id, out val);
var value = ((val > 0) ? val.ToString() : string.Empty);
// compute the element name (for dictionary binding)
string id = "cbts_{0}".FormatMe(template.Id);
string dictKey = "cbts[{0}].Key".FormatMe(counter);
string dictValue = "cbts[{0}].Value".FormatMe(counter++);
%>
<input type="hidden" name="<%= dictKey %>" value="<%= template.Id %>" />
<input type="text" id="<%= id %>" name="<%= dictValue %>" value="<%= value %>" />
<label for="<%= id %>"><%= template.Name %></label>
<br />
<% }
%>
I had to add a hidden field to store the value.
I introduced a 'fake' counter just to loop over the dictionary the way ASP.Net MVC wants it.
As a result I got a dictionary filled with my values and '0' when the textbox is empty.
Another problem appeared: the ModelState was considered not valid because "a value is required". I don't want my values to be required, but looking at the modelbinder code, I did not found a way to tell the binder that a value is NOT required.
So I tricked the ModelState in my controller, removing all error, like this:
public ActionResult Save(int? id, Dictionary<int, int> cbts)
{
// clear all errors from the modelstate
foreach(var value in this.ModelState.Values)
value.Errors.Clear();
Well... I effectively got a solution, but the HTML is kind of ugly now, and counterintuitive (using an index to loop over a non-indexed collection ??).
And I need to trick each time I'll use this kind of binding to have it all work properly.
So I will now open a new post to make dictionary binder something better.
Here it is: ASP.Net MVC 2 - better ModelBinding for Dictionary<int, int>
EDIT - There is a cleaner solution, thanks to Pavel Chuchuva.
In the controller code, use a nullable int as value for the dictionary.
A bit more code to add, but much cleaner.
public ActionResult Save(int? id, Dictionary<int, int?> cbts)
{
// this is our final dictionary<int, int>
Dictionary<int, int> cbtsFinal = new Dictionary<int, int>();
// loop on the dicitonary with nullable values
foreach(var key in cbts.Keys)
{
// if we have a value
if(cbts[key].HasValue)
// then put it in the final dictionary
cbtsFinal.Add(key, cbts[key].Value);
}