I have some jsf-code with a tag that is re-rendered by an ajax call. It contains something like
<h:outputScript>alert("Gotcha")</h:outputScript>
but this is only executed on first load, not on an ajax induced partial render.
This is but a minimal example, what I'm really trying to do is to trigger some server-generated javascript right after the ajax-call has returned, something like
<h:outputScript>#{scriptBean.getScript()}</h:outputScript>
I've seen calling .trigger("click") that is in javascript code returned from an ajax call, Asynchronize ajax calls and javascript code, how to run call some Javascript code with jQuery as soon as element loads to page by Ajax? and Running javascript code called by AJAX, but neither questions nor answers look like they address my question, least not without some additional hint or explanation.
And because I want to keep things small and simple, and because I could avoid anything above jsf:core (mostly), I'd prefer solutions that avoid using yafl (== yet another fancy library).
Edit: as for the comment from @BalusC I post more context:
<composite:implementation>
<h:form id="${cc.attrs.imgId}" styleClass="small" onchange="alert('Gotcha0');">
<f:event type="postAddToView" listener="#{mBean.register}" />
<f:event type="preRenderView" listener="#{mBean.init}" />
<f:attribute name="flav" value="#{cc.attrs.flav}" />
<h:graphicImage width="${cc.attrs.width}" id="${cc.attrs.imgId}"
onclick="if (event.isTrusted) this.nextSibling.value=mods(event);"
onmouseover="aa=this.id" alt="not found"
onchange="alert('Gotcha1');"
value="images/img?#{cc.attrs.flav}=#{mBean.getNextCount()}&imgId=#{cc.attrs.imgId}">
<f:ajax event="click" execute="@form"
onevent="function(data) { if (data.status === 'success') {
console.log('HiHo'+data.responseCode+'\n\n'+ data.responseText+'\n\n'+data.responseXML);
me=window.document.getElementById('#{cc.clientId}:#{cc.attrs.imgId}:#{cc.attrs.imgId}');
me.nextSibling.nextSibling.value=0;
me.nextSibling.value=0;
me.myfunc=function(event)
{
console.log('keyCode='+event.keyCode+' mods='+mods(event)+'/'+this.nextSibling.id);
this.nextSibling.value=mods(event);
this.nextSibling.nextSibling.value=String.fromCharCode(event.keyCode);
this.click();
}; }; }"
listener="#{mBean.handleEvent}" render="@this">
</f:ajax>
</h:graphicImage>
<h:inputHidden id="m" value="#{mBean.keyX}" />
<h:inputHidden id="k" value="#{mBean.key}" />
</h:form>
<h:outputScript>alert("Gotcha2")</h:outputScript>
<h:outputScript>var i=0;window.document.getElementById('#{cc.clientId}:#{cc.attrs.imgId}:#{cc.attrs.imgId}').myfunc=function(event)
{
aa='#{cc.clientId}:#{cc.attrs.imgId}:#{cc.attrs.imgId}';
this.nextSibling.value=mods(event);
this.nextSibling.nextSibling.value=String.fromCharCode(event.keyCode);
this.click();
};
</h:outputScript>
</composite:implementation>
"Gotcha2" shows up only at load time, once for each instance of the composite, but not when the component is re-rendered via ajax calls.
"Gotcha0" and "Gotcha1" are completely ignored.
The "HiHo" shows up for every ajax-call on the component, but I would like the function to fire only when the component is rendered, which is a subtle difference, because I might manipulate the render-list on server side, like
private void addToRenderMap(String obj) {
FacesContext context = FacesContext.getCurrentInstance();
Collection<String> renderIds = context.getPartialViewContext().getRenderIds();
renderIds.add(obj);
}
or even remove the calling component from the list. (For example, for keypress "i", I want to only show image information in some other component and avoid unnecessary re-sending of the image data.)
Edit2: I see that onchange really is more a onvaluechange for fields that take input, so it's not a big surprise that this part of the code is ignored.