here is what I'm trying to do.
My ADF page is embedded inside a web page and I must set some values in the parent window.
To do so I have a javascript function that does the work just fine. to get the value I need to push, I must call an external API with some parameter that depend on a user click.
I implement the call in my manage bean, I get the value and I push it in an input field on my page.
I also setup a clientListener(valueChange) on the inputfield to call my javascript function.
In theory it should do just fine.
the issue is that after the user invoked my serverListener event that call the API, the clientListener is not invoked when the value is pushed inside the inputfield.
I've let the field visible for testing and I can enter the value myself and it work but when the bean push the value in the field the valueChange event doesn't get trigger.
The question from there is how do I get the event to trigger after the bean retrived the value, or how do I call the javascript function from the bean directly ?
here is a sample of the code I use
<af:resource type="javascript">
function pushValue(evt){
// push values to parent page
window.external.main.setFieldValue("fieldName", evt.getSource().getValue());
}
function callServerAPI(){
// call the serverListener
AdfCustomEvent.queue(it2, "callAPI", {somevalues}, true);
}
</af:resource>
<af:inputText label="My hidden field"
id="it2"
binding="#{pageFlowScope.MyAppBean.hiddenField}"
clientComponent="true">
<af:clientListener method="pushValue" type="valueChange"/>
<af:serverListener type="callAPI"
method="#{pageFlowScope.MyAppBean.callAPI}"/>
</af:inputText>
here is the sample for the bean
private RichInputText hiddenField;
public void callAPI(ClientEvent clientEvent) throws Exception {
String fieldValue = clientEvent.getParameters().get("somevalues").toString();
try {
// call the API and get the value needed in the hidden field
hiddenField.setValue(fetchValue(fieldValue));
} catch (Exception e) {
e.printStackTrace();
}
// refresh field
AdfFacesContext.getCurrentInstance().addPartialTarget(hiddenField);
}
Thanks in advance for the help !
This article https://cedricleruth.com/how-to-execute-client-javascript-in-an-adf-java-bean-action/ answer your question : "how do I call the javascript function from the bean directly ?" as follow :
/*** In YOURJSF.jsf button, or other component that need to execute a javascript on action, add : ****/
<af:commandButton text="ClickMe" id="cb1" actionListener="#{YOURSCOPE.YOURJAVABEAN.clickToExecuteJavascriptAction}"/>
/*** In YOURJAVABEAN.java class add : ***/
public void clickToExecuteJavascriptAction(ActionEvent actionEvent) {
this.executeClientJavascript("console.log('You just clicked : " + actionEvent.getSource() + " ')");
//Note: if you use a java string value in this function you should escape it to avoid breaking the javascript.
//Like this : stringValue.replaceAll("[^\\p{L}\\p{Z}]", " ")
}
//You should put this function in a util java class if you want to use it in multiple bean
public static void executeClientJavascript(String script) {
FacesContext facesContext = FacesContext.getCurrentInstance();
ExtendedRenderKitService service = Service.getRenderKitService(facesContext, ExtendedRenderKitService.class);
service.addScript(facesContext, script);
}