1

I'm developing a simple JSF application, but I'm stuck again...

Basically, I have a person who is logged in and wants to post a new message:

<h:form id="messageform">
    <div style="width:900px; margin-top:-20px;">
        <div id="count">250</div>
        <div id="barbox"><div id="bar"></div></div>
        <h:inputTextarea id="textarea_message" cols="8" rows="5" value="#{messageBean.message}" />
    </div>
    <h:commandButton id="message_submit" value="" action="#{messageBean.postMessage(login.username)}" styleClass="input-submitbericht" />
</h:form>

And the postMessage method that is in the messageBean.

public void postMessage(String username) {
    Message.clearMessage();
    System.out.println(db.getAlleBerichten().size());
    if (Message.checkValidMessage(message) && Message.checkValidUsername(username)) {
        Gebruiker g = db.readGebruiker(username);
        db.addBerichtBijGebruiker(g, message);
        Message.setMessage("Uw bericht is succesvol gepost!");
        Message.setMessageType("info");
        Message.setRenderMessage(true);
        System.out.println(db.getAlleBerichten().size());
    }
}

This code works perfectly. I used a simple System.out.println() in my messageBean, and the element gets added perfectly.

Now, when I try to display the new message on the screen, it simply doesn't get detected. It's like the element never got added to the ArrayList...

I use this code for displaying the messages:

<ui:repeat value="#{database.alleBerichten}" var="berichten">
    <div class="record">
        <div class="#{(rowCount % 2) != 0 ? 'posteven' : 'postodd'}">
            <div class="text_wrapper text_wrapperm#{berichten.id}">
                #{berichten.bericht}
            </div>
            <div class="edit editm#{berichten.id}" style="display:none; width:890px;">
                <textarea class="editbox editboxm#{berichten.id}" cols="23" rows="3" id="m#{berichten.id}" method="message"></textarea>
            </div>
            <div class="postinfo"> door #{berichten.gebruiker.gebruikersnaam}
                <c:if test="#{berichten.gebruiker.gebruikersnaam == login.username}">
                    <h:form>
                        <a style="cursor: pointer;" class="edit_link" title="Edit" id="m#{berichten.id}">Wijzigen</a> -
                        <h:commandLink value="Verwijderen" action="#{database.deleteBericht(berichten.id)}" styleClass="delbutton"/>
                    </h:form>
                </c:if>
            </div>
        </div>
    </div>
    <c:set var="rowCount" value="#{rowCount + 1}"/>
</ui:repeat>

So I think the problem is with the ui:repeat part, but I don't know how I can fix this...

Arolition
  • 15
  • 4

1 Answers1

1

You have a JSTL <c:if> tag inside JSF <ui:repeat> tag. It's important to understand that JSTL and JSF doesn't run in sync as you'd expect from the coding. It's JSTL which runs first during view build time and generates a view with JSF tags only. Then JSF runs during view render time and generates HTML output.

The object behind var attribute of JSF <ui:repeat> is thus never available when the JSTL <c:if> tag runs. You want to use a JSF tag/attribute instead. In this particular case, the rendered attribute is appropriate.

So, replace

<c:if test="#{berichten.gebruiker.gebruikersnaam == login.username}">
    <h:form>
        <a style="cursor: pointer;" class="edit_link" title="Edit" id="m#{berichten.id}">Wijzigen</a> -
        <h:commandLink value="Verwijderen" action="#{database.deleteBericht(berichten.id)}" styleClass="delbutton"/>
    </h:form>
</c:if>

by

<h:form rendered="#{berichten.gebruiker.gebruikersnaam == login.username}">
    <a style="cursor: pointer;" class="edit_link" title="Edit" id="m#{berichten.id}">Wijzigen</a> -
    <h:commandLink value="Verwijderen" action="#{database.deleteBericht(berichten.id)}" styleClass="delbutton"/>
</h:form>

Also the JSTL <c:set> tag isn't going to work here. If you're using JSF 2.0, use the varStatus attribute of the <ui:repeat> instead.

<ui:repeat value="#{database.alleBerichten}" var="berichten" varStatus="loop">
    <div class="record">
        <div class="#{(loop.index % 2) != 0 ? 'posteven' : 'postodd'}">
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Ok, I didn't knew that JSTL & JSF don't run in sync. But the new messages that a user posts still aren't added to the output... – Arolition Apr 10 '11 at 12:54
  • This problem is then caused by something else. Ensure that the `db` instance in your message bean and that the `#{database}` reference in EL refers to exactly the same instance. – BalusC Apr 10 '11 at 12:57