How to call listener or backing bean method after completing a javascript call in jsf

event-handlingjsfjsf-2jsf-2.2

According to my scenario, Need to invoke the javascript first. After the javascript call two hidden values will be updated. With the updated hidden values , have to call Bean method. In this scenario, I am getting called javascript and bean method at the same time. So In my bean method, I am not getting the updated values in the hidden fields.

Little bit detail explanation

Textbox(address) is used to type address. And having two hidden elements which will used to store street name and city name based on the address field.

By the Javascript call, Collecting two values (Street name and City name) from the google maps API (codeAddress()). Based on the entered address in the textbox updating the two hidden fields(street and city). Bean method has to handle With the updated hidden values.

But From my code, Backing bean and the java script is called simultaneously. So I am not getting the Updated value in the Backing Bean.

My code is following :

JSF CODE

<h:form prependId="false">
    <div id="panel-one">
        <h:outputLabel value="ADDRESS"/>
        <h:inputText type="text" id="address" size="40" value="#{Bean.address}"/>
        <h:inputHidden id="street" value="#{Bean.streetName}" />
        <h:inputHidden id="city" value="#{Bean.city}" />
        <h:commandButton type="submit" value="Verify Address"
            onclick="checkAddress()">
            <f:ajax execute="@form" render="@none" listener="#{Bean.checkAddress()}"/>
        </h:commandButton>
    </div>
</h:form>

Javascript

checkAddress() {
    document.getElementById("street").value = //Setting value from other javascript API;
    document.getElementById("city").value = //Setting value from other javascript API;
}

In the above javascript collecting values and setting it with two textbox. With the updated values again calling the checkAddress() method in backing bean. FYI : *checkAddress()* is a AJAX CALL. I am doing mistake in h:commandButton of JSF , but dont know how to fix it. Any help is much appreciated.

Best Solution

There're several things odd with your provided code:

  • I don't see a need for prependId
  • Defining onclick on a commandButton is a bad idea[tm]
  • You're setting yourself and/or the person inheriting that code up for a headache by having a JS function and a bean method both called checkAddress
  • You don't seem to do anything based upon the fired action? (having render="@none")

That said, a kind of hack that should do what you need is hiding the actual button and clicking it programmatically:

<h:form id="addrF">
    <h:outputLabel value="ADDRESS"/>
    <h:inputText type="text" id="address" size="40" value="#{bean.address}"/>
    <button class="clickMe">Verify Address</button>

    <h:inputHidden id="street" value="#{bean.streetName}" />
    <h:inputHidden id="city" value="#{bean.city}" />

    <h:commandButton id="submitBtn" style="display:none;">
        <f:ajax execute="@form" render="@none" listener="#{Bean.checkAddress()}"/>
    </h:commandButton>
</h:form>
<h:outputScript>
    $(".clickMe").click(function(ev) {
        ev.preventDefault();
        $.getJSON(
             "https://maps.googleapis.com/maps/api/geocode/json", 
             { address : $("#addrF\\:address").val() },
             function(data) {
                 // set street, city
                 $('#addrF\\:submitBtn').click();
             }
         );
    });
 </h:outputScript>

You probably want additional value validation, etc. and your access to the maps API might be different (I haven't used it at all). The point is: you need to click() on the hidden commandButton only after your ajax call completed.

Related Question