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.

ArunRaj
  • 1,780
  • 2
  • 26
  • 48
  • Why don't you just remove "actionListener" attribute and just do same thing with validators? Or else move that logic in submit method. – mitpatoliya Mar 25 '14 at 06:40
  • @mitpatoliya : Can you please explain little bit more. What do you mean by submit method ? – ArunRaj Mar 25 '14 at 06:50
  • @mitpatoliya : Removed actionListener attribute from commandButton and placed listener attribute in ajax tag. Still the same result. Is it what you have tried to say ? – ArunRaj Mar 25 '14 at 07:02
  • Since you need to populate your bean data from javascript when user clicks, why didn't you try to pass your data from js to backing bean? – Maozturk Mar 25 '14 at 08:55
  • @Maozturk : Interesting, I dont know the way to implement. If you know , please give me some tips to be implement. Having doubt in the approach, If we calling backbean from JS (is it secure way of coding ?), It will become anyone to call our Backing bean from the Javascript. – ArunRaj Mar 25 '14 at 09:01
  • 1
    But it is possible with primefaces, if you still interested in, then you can use the approach which is in this article : http://stackoverflow.com/questions/18975746/how-to-call-managed-bean-methods-with-parameters-via-javascript Security depends on your implementation for sure. – Maozturk Mar 25 '14 at 15:16
  • I'm confused: your *Javascript* function causes one/several AJAX calls? Also, what does your bean method do you can't do in javascript (since it doesn't produce any output)? I think you're much better served by describing what the process looks like and what the outcome after the click on that button should be. – mabi Mar 26 '14 at 08:06
  • @mabi : Really sorry for putting up a question in confusing manner. Updated the Question. Please find it and help me if possible. – ArunRaj Mar 26 '14 at 09:22

3 Answers3

2

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.

mabi
  • 5,279
  • 2
  • 43
  • 78
0

Please try using event="" in f:ajax and then use onevent to call javascript function. Event value would be "click" and onevent value would be name of javascript function. like

  • In the above approach, we could trigger the javascript call. But can not invoke the javascript call before the listener call. Please go through my scenario. – ArunRaj Mar 25 '14 at 09:53
  • 1
    i have used same in my project .. my situation is that listner should get called only for some of the selected values in dropdown. that i couldn't stop so i call a javascript function before listener which replaces the new value with null and my listener does nothing when it gets null value. Hope it will solve ur issue – Sudhanshu Mar 27 '14 at 04:54
0

You could try to set a Delay for the JavaScript setTimeout()

<h:commandButton type="submit" value="Verify Address"
            onclick="setTimeout(function(){checkAddress()},1000);">

1000 miliseconds = 1 second, you just change that value for your convenience

Alex Andrade
  • 342
  • 1
  • 3
  • 14
  • Javascript has to invoked first, before the JSF action call. Will it helpful ? – ArunRaj Mar 26 '14 at 04:09
  • sorry i misunderstood, try (in your Backing Bean) this RequestContext context = RequestContext.getCurrentInstance(); context.update("yourForm:yourComponent"); these lines must be at the very end in your bean method – Alex Andrade Mar 26 '14 at 15:19