Tiago Peres França
Tiago Peres França

Reputation: 3215

How do I detect a render event in a form using JSF?

consider the following form in a JSF page:

<h:form id="countForm">
  <h:outputText value="#{myBean.count}" />
  <h:commandButton value="Increment the count!">
    <f:ajax listener="#{myBean.increment()}" render="@form" />
  </h:commandButton>
</h:form>

This simple code will increment the counter whenever the user clicks the button, via ajax requests.

Suppose I'd also like to show the user an alert informing the new value of the counter whenever the form is updated (rerendered). How would I do that? Is there anything like the code below?

<h:form onUpdate="alert('the new value is #{myBean.count()}')">

I know I could use the "oncomplete" method of primefaces, but the event would be linked to the button instead of the form, that's not what I want.

A counter is not what I'm trying to do, this is just a simple example to better show my problem.

Thank you in advance for any help.

Upvotes: 3

Views: 6360

Answers (4)

JScoobyCed
JScoobyCed

Reputation: 10413

There is one way that is not greatly elegant, but I am using it in scenario where I am stuck with no other alternative. I am using a <h:panelGroup> that contains a <script> block, and I use the panelGroup id in the render= part of the <f:ajax part

<h:form id="countForm">
  <h:outputText value="#{myBean.count}" />
  <h:commandButton value="Increment the count!">
    <f:ajax listener="#{myBean.increment()}" render="postAjax" />
  </h:commandButton>
  <h:panelGroup id="postAjax">
    <script>
     //...
    </script>
  </h:panelGroup>
</h:form>

Note this will not work well if the panelGroup is inside a ui:repeat or datatable.

Upvotes: 0

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

You can use an ajax status tag component from PrimeFaces: <p:ajaxStatus> or RichFaces: <a4j:status> (link to its documentation). Both components handle the start and complete events from an ajax call made in the form.

I haven't tried any of these in a JSF 2 application, but I would recommend using the PrimeFaces one (at least the documentation is better than RichFaces). I've used the RichFaces <a4j:status> in a JSF 1.2 + RichFaces 3.3 application to show/hide a dialog to the user for any ajax request. It looked like this (and could give you an idea):

<a4j:status onstart="Richfaces.showModalPanel('mdpWaitMessage')" 
    onstop="Richfaces.hideModalPanel('mdpWaitMessage')" />
<!-- defining the modal (popup) panel to show the user there was an ajax action -->
<rich:modalPanel id="mdpWaitMessage" resizeable="false" zindex="5000"
    minHeight="30" minWidth="10" height="70" width="150">
    <f:facet name="header">
        <h:outputText value="#{aplicacion.waitMessageTitle}" />
    </f:facet>
    <h:graphicImage value="#{aplicacion.waitMessagePath}" />
    <h:outputText value="#{aplicacion.waitMessageDescription}" />
</rich:modalPanel>

Upvotes: 1

prageeth
prageeth

Reputation: 7395

Its difficult to provide a exact answer because your exact requirement is not clear.
1. Did you try the <a4j:form> which has onComplete event? Didn't it solve your problem?
2. If you absolutely need to run the script after the form is reRendered you can put <script> tags inside the form and put the javascript code inside them as below.

<h:form id="frm">
  <script>
    alert('#{myBean.count()}');
  </script>
</h:form>

This alert is displayed each time the form is rendered.
Note that if you need to prevent this JS run at page loading you may need to add a condition as below.

<head>
  <script>
    var showAlert = false;
  </script>
</head> 
<body>
<h:form id="frm">
  <script>
    if(showAlert) {
      alert('#{myBean.count()}');
    }
    showAlert = true;
  </script>
</h:form>
</body>

Upvotes: 2

stg
stg

Reputation: 2797

Take a look at javax.faces.event.PreRenderComponentEvent.

<h:form id="myForm">
  <f:event type="preRenderComponent"
           listener="#{someActionListener}" />
</h:form>

Each time you (re-)render your form, the actionListener will be called first.

Upvotes: 0

Related Questions