i have a repeating form like this:
<ui:repeat var="blogPost" value="#{blogPosts}">
<h:form>
<div class="full">
<label for="newcomment">write a comment<br/></label>
<h:inputTextarea value="#{commentController.commentText}" id="commentText" rows="10" cols="40" />
</div>
<div class="full">
<h:commandButton action="#{commentController.setComment()}" value="write comment">
<f:setPropertyActionListener target="#{commentController.blogPostId}" value="#{blogPost.id}" />
</h:commandButton>
</h:form>
</ui:repeat>
I found this Post form BalusC – helped me a lot so i have now the blogPostID in my controller!
But the problem is:
The form is repeating 1 – x times!
So, if i have 3 forms rendered, all textareas use the same commentController.commentText
So if i write something in the first textarea, the 2nd and 3rd are deleting the commentText in the Controller.
If i put something into the 3rd textarea, it works!
Any idea how to fix tis problem?
thanks in advance!
p.s. i also tried to have the <h:form> outside the <ui:repeat> – makes no difference
Here are the classes:
The Controller:
@ManagedBean(name="commentController")
@RequestScoped
public class CommentController {
@EJB
private CommentProvider commentProvider;
private String commentText;
private List<String> commentTextListToWrite;
private Comment comment;
private Integer blogPostId;
@PostConstruct
protected void init(){
comment = new Comment();
commentTextListToWrite = new ArrayList<String>();
}
public void setComment(){
int count = 0;
for (String ct : commentTextListToWrite) {
System.out.println("test " + count + ct);
count++;
}
}
/**
* Returns the commentText.
*
* @return the commentText.
*/
public String getCommentText() {
return commentText;
}
/**
* Sets the commentText.
*
* @param commentText the commentText to set.
*/
public void setCommentText(String commentText) {
this.commentText = commentText;
}
public void delete(Comment comment){
commentProvider.delete(comment);
}
/**
* Returns the blogPostId.
*
* @return the blogPostId.
*/
public Integer getBlogPostId() {
return blogPostId;
}
/**
* Sets the blogPostId.
*
* @param blogPostId the blogPostId to set.
*/
public void setBlogPostId(Integer blogPostId) {
this.blogPostId = blogPostId;
}
/**
* Returns the commentTextListToWrite.
*
* @return the commentTextListToWrite.
*/
public List<String> getCommentTextListToWrite() {
return commentTextListToWrite;
}
/**
* Sets the commentTextListToWrite.
*
* @param commentTextListToWrite the commentTextListToWrite to set.
*/
public void setCommentTextListToWrite(List<String> commentTextListToWrite) {
this.commentTextListToWrite = commentTextListToWrite;
}
}
index.xhtml:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:c="http://java.sun.com/jsp/jstl/core"
template="/WEB-INF/templates/default.xhtml">
<ui:define name="content">
<h2>Show all BlogPosts</h2>
<ui:repeat var="blogPost" value="#{blogPosts}" varStatus="loop" >
<h:form>
<div class="posting">
<h3>#{blogPost.headline}</h3>
<div class="posts">#{blogPost.blogPost}</div>
<div class="posts">
vom #{blogPost.date} mit ID: #{blogPost.id}<br />
<h:commandButton value="delete" action="#{blogPostController.delete(blogPost)}" />
</div>
</div>
<ui:include src="pages/components/_write-comment.xhtml">
<ui:param name="blogPostId" value="#{blogPost.id}" />
<ui:param name="loopCount" value="#{loop.index}" />
</ui:include>
</h:form>
</ui:repeat>
</ui:define>
</ui:composition>
_write-comment.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<div class="full">
<span class="half">
<label for="newcomment">write comment</label><br/>
<h:outputLabel for="commentText" value="loop index #{loopCount}" />
<h:inputTextarea value="#{commentController.commentText[loopCount]}" id="commentText" rows="10" cols="40">
</h:inputTextarea>
</span>
<span class="quarter error">
<h:message id="newcomment_error" for="newcomment" value="fehler" />
</span>
</div>
<div class="full">
<h:commandButton action="#{commentController.setComment()}" value="write comment">
</h:commandButton>
</div>
</ui:composition>
is the Setter of the List correct?
there is (at the moment) no real error, but the system out fails, because the list is empty (the System.Out just stands for another function… it’s just for testing!)
Can you please post the Managed Bean code as well.
From what I can see the
commentTextattribute in yourcommentControlleris a simpleStringinstead of aList<String>. When you have for example three text areas you must have three different variables which should store the textarea content. This is why you need a list there.Here you can read some more details because I had the same problem as you.
Knowing all that your code should look like this:
Managed Bean:
Facelet:
Some other pointers:
<br />in the label tag.idattribute. It should be the same as that linked by the label. If not, you will receive some view warnings because the framework will not be able to find the IDs you specified. Don’t worry about the IDs being identical in theui:repeatloop. If you analyse the HTML code you’ll see that SF handle the IDs and they differ.LE:
I think that the reason you are having this problem is that you allocated memory for the
List<String>but the list does not contain any String. The framework wants to place values into theListbut there is noStringobject to be setted.To solve this, in the
CommentControlleryou have to add the needed empty Strings into the List:blogPosts.size()is the blogPosts attribute you are using on the<ui:repeat>tag. I can imagine that you are able to access it in theCommentControlleras well. This way, every time you instantiate aCommentControllerentity, thecommentTextListToWritewill be instantiated and will contain the required number of empty Strings which will be completed on the view.