I have created a composite component that extends the command button and add some ajax functions (onBegin, onComplete and onSuccess), but I have some problems that I couldnt solve:
When I click on the button and a validation error occur, in success event function is passed #{facesContext.validationFailed} = false instead of true even thought the form is render again; (html is render before a success event called, right?)
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
<cc:interface shortDescription="CommandButton com Ajax">
    <cc:attribute name="onbegin"/>
    <cc:attribute name="oncomplete"/>
    <cc:attribute name="onsuccess"/>
    <cc:attribute name="render"/>
    <cc:attribute name="execute"/>
    <cc:attribute name="action" targets="commandButton"/>
    <cc:attribute name="actionListener" targets="commandButton"/>
    <cc:attribute name="value"/>
    <cc:attribute name="styleClass" targets="commandButton"/>
    <cc:attribute name="immediate" targets="commandButton"/>
</cc:interface>
<cc:implementation>
    <h:outputScript library="progutils" name="/js/commandButton.js" target="HEAD"/>
    <h:commandButton id="commandButton" value="#{cc.attrs.value}">
        <f:ajax render="#{cc.attrs.render}" execute="#{cc.attrs.execute}"
                onevent="function(data){execCommandButtonAjax(data, function(){ #{cc.attrs.onbegin} },function(){ #{cc.attrs.oncomplete} },function(){ #{cc.attrs.onsuccess} }, #{facesContext.validationFailed})}">
        </f:ajax>
    </h:commandButton>
</cc:implementation>
</html>
Javascript File
function execCommandButtonAjax(data, onBegin, onComplete, onSuccess, validationFailed) {
    var status = data.status;
    switch (status) {
        case 'begin': {
            onBegin();
            break;
        }
        case 'complete': {
            onComplete();
            break;
        }
        case 'success': {
            console.log('Validation Failed ' + validationFailed);
            if(!validationFailed){
                onSuccess();
            }
            break;
        }
    }
}
Using the component:
<pu2:commandButton id="btnPu2" 
                   onbegin="block(); console.log('begin')"                                                                    
                   oncomplete="unblock(); console.log('complete')"
                   onsuccess="console.log('success')"
                   execute="@form"
                   action="#{list.search()}"
                   render="@form :table-form :form-pagination"
                   value="Do it">
</pu2:commandButton>
				
                        
EL expressions are evaluated while generating HTML output. They are not evaluated during JavaScript events or so. Rightclick and View Source. You see, it's one and all HTML/JS. No JSF components, no EL expressions. JSF is "just" a HTML code generator.
So when you load the page,
#{facesContext.validationFailed}will printfalse. Exactly this value is being passed as JS function argument. It will only work if you re-render the JSF component responsible for printing#{facesContext.validationFailed}before passing it as JS function argument.Standard JSF offers no facilities to pass additional information to the ajax response. Component libraries like PrimeFaces and OmniFaces support this via a custom
PartialViewContext. PrimeFaces has even a builtinvalidationFailedproperty in itsargsobject which is available in anyoncompleteattribute.Your best bet is to conditionally render
onsuccessscript itself.