Show hidden elements using JSF and AJAX

I am having some trouble using JSF with AJAX to render a table without reloading the entire page on every form submission.

When I first start the server, my database is empty, so only the form to add books should be displayed on the page. When the user submits the form, it is assumed to be displayed fieldset

when all books are displayed. I don't want this to fieldset

be displayed when the database is empty.

This is a simple version of my code (it's a small form and table that needs to be updated with AJAX):

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">

<h:head />
<h:body>
<h:graphicImage library="img" name="caelum-logo.png"/>

<h:form>
    <p>Book Title:</p>
    <h:inputText id="title" value="#{livroBean.livro.titulo}" />
    <h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
        <f:ajax execute="@form" render="title :addedBooksTable" />
    </h:commandButton>
</h:form>

<div id="addedBooksTable">
    <p:fieldset rendered="#{livroBean.numberOfBooks > 0}">
        <h:dataTable value="#{livroBean.allBooks}" var="book">
            <h:column>
                <h:outputText value="#{book.titulo}" />
            </h:column>
        </h:dataTable>
    </p:fieldset>
</div>

</h:body>
</html>

      

And I want to focus on this part:

<h:commandButton value="Add book" action="#{livroBean.addFirstBook}">
    <f:ajax execute="@form" render="title :addedBooksTable" />
</h:commandButton>

      

The grid and the table inside it should be hidden when no workbook is added to the database, which is why I used <p:fieldset rendered="#{livroBean.numberOfBooks > 0}">

. But I want it to be displayed after the button is clicked commandButton

, even if there is inputText

nothing in it.

This is what happens when checking the code:

  • If I test the code in the same way as in an empty database, it is updated inputText

    (it "erases" what was entered before submitting) when I click on commandButton

    , but the fieldset is not. I know the fieldset has rendered="#{livroBean.numberOfBooks > 0}"

    and the inputText does not, but the method getNumberOfBooks

    is called every time I press the commandButton, so I don't understand it ...
  • if i change the tag f:ajax

    so that it ends this way <f:ajax execute="@form" onevent="click" render="title :addedBooksTable" />

    it solves the problem but i can implement the screen flashing for a while when i click commandButton

    . As far as I know, one of the uses of AJAX is that we don't want the screen to blink when a request is made.

Why fieldset

is it only displayed when I use onevent="click"

? Should I consider something normal? Is there a more elegant solution for this?

Thank!

+3


source to share


1 answer


You cannot ajax update a simple HTML element. You can only ajax update the JSF component. The simple reason is that the target must be resolvable UIViewRoot#findComponent()

, so JSF can find it in the component tree and display the updated HTML in the Ajax response.

Replace

<div id="addedBooksTable">

      

by



<h:panelGroup layout="block" id="addedBooksTable">

      

Typically this should have thrown the exception described in How do I find out the client ID for an ajax update / render? Cannot find component with expression "foo". referring to "bar" but they removed this check in Mojarra 2.2.5 to support ajax update of a particular iteration <ui:repeat>

and <h:dataTable>

(this missing check will be fixed later really useless for beginners like you).

As for why the application is onevent="click"

running, this is because it triggered a JavaScript error, which in turn caused the entire JavaScript / Ajax object to collapse, which in turn caused the command button to reject the default synchronous behavior with full page reload (as if you are not using at all <f:ajax>

). You probably used instead event="click"

. The attribute onevent

has a different purpose. See also ao proclick onclick function after ajax <f: ajax> call .

+3


source







All Articles