Onevent option ignored for jsf.ajax.request?

I am trying to create a live chat web application using Java EE 7, specifically using JSF 2.2 with ajax.

The idea is that there is always one pending asynchronous ajax request pending on the server for each individual client. When a new message arrives at the server, all wait requests are returned so that the messages appear on all clients. Upon completion of requests, new wait requests are sent by clients. If the message is not received within 30 seconds, the request is returned so that a new one can be submitted before old age.

I could make it work like this:

index.xhtml:

<?xml version='1.0' encoding='UTF-8' ?>
<!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://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">

    <h:head>
        <title>async jsf app</title>
        <h:outputScript library="js" name="resendscript.js" />
    </h:head>
    <h:body> 

        async jsf app
        <h:form id="jsfappform">
            say something: 
            <h:inputText id="newmsg" value="#{jsfAsync.newMessage}" />
            <h:commandButton id="sendbut" value="say" action="#{jsfAsync.say}" />
            <br /><br />
            Messages:
            <br /><br />
            <h:outputText id="msgs" value="#{jsfAsync.msgs}" escape="false">
                <h:outputScript>resendRequest()</h:outputScript>
            </h:outputText>            
            <h:commandButton id="reloadbut" value="" action="#{jsfAsync.resend}" style="visibility: hidden">
                <f:ajax execute="@this" render="msgs" onevent="handleAjax" onerror="handleError" /> 
            </h:commandButton>
            <h:commandButton id="clearbut" value="clear" action="#{jsfAsync.clear}" />
            <h:outputScript>resendRequest()</h:outputScript>
        </h:form>
    </h:body>
</html>

      

resendscript.js:

function handleAjax(data) 
{
    var status = data.status;
    switch(status) 
    {
        case "success": resendRequest();
                        break;
    }
}

function handleError(data) { }

function resendRequest() 
{
    document.getElementById("jsfappform:reloadbut").click();
} 

      

JsfAsync.java bean support:

package jsfasync;

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ApplicationScoped;

@ManagedBean
@ApplicationScoped
public class JsfAsync 
{
    private final List<String> messages;
    private final Object wakeup;

    public JsfAsync() 
    {
        wakeup = new Object();
        messages = new ArrayList<String>(); 
    }

    public void setNewMessage(String msg)
    {
        synchronized(messages)  {  messages.add(msg); }            
    }

    public void say()
    {  
        synchronized(wakeup)  {  wakeup.notifyAll();  }
    }

    public void resend()
    {         
        try { 
          synchronized(wakeup)  {  wakeup.wait(30000);  }
        } catch (Exception e) { }    
    }

    public void clear()
    {
        synchronized(messages)  {  messages.clear();  }
        say();
    }

    public String getNewMessage() {  return ""; }

    public String getMsgs()
    {
        StringBuilder msgs = new StringBuilder();
        synchronized(messages)
        {
            for (String m : messages)
            {
                msgs.append(m);
                msgs.append("<br />");
            }        
            return msgs.toString();
        }
    }
}

      

I would like to replace the body of the resendRequest () javascript function with ajax API like this:

jsf.ajax.request('jsfappform:reloadbut', null, 
                 {'javax.faces.behavior.event': 'action', 
                  'execute': 'jsfappform:reloadbut', 
                  'render': 'jsfappform:msgs', 
                  'onevent': 'handleAjax',
                  'onerror': 'handleError'});

      

Unfortunately, I cannot get it to work this way. The call can complete the ajax request, but it seems that the onevent parameter was ignored and the event handler was not called when this request completed. Perhaps you have some hints on how to make it work this way?

+3


source to share


1 answer


Check the generated HTML source for hints <h:commandButton id="reloadbut">

. You will see that JSF generated it as 'onevent': handleAjax

. Indeed, like a function reference instead of a string.

Correct it accordingly:



jsf.ajax.request('jsfappform:reloadbut', null, 
                 {'javax.faces.behavior.event': 'action', 
                  'execute': 'jsfappform:reloadbut', 
                  'render': 'jsfappform:msgs', 
                  'onevent': handleAjax,
                  'onerror': handleError});

      

+3


source







All Articles