Форма с повторяющейся текстовой областью - как получить переменную? - PullRequest
2 голосов
/ 27 февраля 2012

У меня есть повторяющаяся форма, как это:

<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>

Я нашел это Пост формы BalusC - мне очень помогло, так что теперь у меня есть blogPostID в моем контроллере!

Но проблема в следующем:
Форма повторяется 1 - х раз!

Итак, если у меня есть 3 визуализированные формы, все текстовые области используют один и тот же комментарийController.commentText

Так что, если я что-то напишу в первой текстовой области, 2-й и 3-й удаляют текст комментария в контроллере.
Если я помещу что-то в 3-ю текстовую область, это работает!

Есть идеи, как решить эту проблему?
заранее спасибо!

p.s. я также пытался иметь <h:form> вне <ui:repeat> - без разницы

Вот классы:

Контроллер:

@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>

Правильно ли задан список?

(в настоящий момент) реальной ошибки нет, но выход из системы завершается сбоем, поскольку список пуст (System.Out просто обозначает другую функцию ... это просто для тестирования!)

1 Ответ

3 голосов
/ 27 февраля 2012

Не могли бы вы также опубликовать код управляемого бина.Из того, что я вижу, атрибут commentText в вашем commentController является простым String вместо List<String>.Например, если у вас есть три текстовых области, у вас должно быть три разных переменных, в которых должно храниться содержимое текстовой области.Вот почему вам нужен список.

Здесь вы можете прочитать некоторые подробности, потому что у меня была та же проблема, что и у вас.

Зная все, что должен выглядеть ваш кодкак это:

Управляемый компонент:

private List<String> commentText;
// get& set

Facelet:

<ui:repeat var="blogPost" value="#{blogPosts}" varStatus = "loop">
<h:form>
    <div class="full">
        <label for="newComment" value = "Write a comment" />
        <h:inputTextarea id = "newComment" value="#{commentController.commentText[loop.index]}" rows="10" cols="40" />
    </div>
    <div class="full">
        <h:commandButton action="#{commentController.setComment()}" value="write comment" />
    </div>        
</h:form>

Некоторые другие указатели:

  • избегайте того, чтобы <br /> в теге label.
  • обращали внимание на атрибут textarea id.Это должно быть то же самое, что связано с ярлыком.Если нет, вы получите несколько предупреждений о просмотре, поскольку платформа не сможет найти указанные вами идентификаторы.Не беспокойтесь о том, что идентификаторы идентичны в цикле ui:repeat.Если вы проанализируете код HTML, вы увидите, что SF обрабатывает идентификаторы, и они различаются.

LE:

Я думаю, что причина, по которой вы имеетеэта проблема в том, что вы выделили память для List<String>, но в списке нет строк.Платформа хочет поместить значения в List, но нет объекта String для установки.

Чтобы решить эту проблему, в CommentController необходимо добавить необходимые пустые строки в список:

@PostConstruct
protected void init(){
    comment = new Comment();
    commentTextListToWrite = new ArrayList<String>();

    for (int i = 0; i < blogPosts.size(); i++){
            commentTextListToWrite.add(new String());
    }
}

blogPosts.size() - это атрибут blogPosts, который вы используете в теге <ui:repeat>.Я могу представить, что вы можете получить к нему доступ также в CommentController.Таким образом, каждый раз, когда вы создаете экземпляр сущности CommentController, создается экземпляр commentTextListToWrite, который будет содержать необходимое количество пустых строк, которые будут завершены в представлении.

...