17

I have an application with a client-side image map with multiple sections defined. I need to call a method in the Managed Bean from the <area> onclick attribute.

This doesn't work:

<area id="ReviewPerson" shape="rect" coords="3, 21, 164, 37" href="#" 
    onclick="#{personBean.method}" alt="Review Person" id="reviewPersonArea"
    title="Review Person" />

Since my hands are tied on the image map (unfortunately), how can I call a managed bean method from within the <area> tag?

maple_shaft
  • 10,435
  • 6
  • 46
  • 74
Jason
  • 3,943
  • 12
  • 64
  • 104

6 Answers6

27

If you use primefaces, you don't need jquery. You use remoteCommand with a name attribute, and call that name from javascript, so:

<area... onclick="somejavascript();"... />

<p:remoteCommand name="myCommand" actionListener="#{personBean.method}" style="display: none;" />

Javascript:

function somejavascript(){
   myCommand();
}
Matthew Oakley
  • 507
  • 1
  • 6
  • 15
  • 7
    Why do I need the additional somejavascript() method? Can we not write `onclick="myCommand();"` ? – Falco Apr 23 '15 at 13:36
  • 2
    @Falco onclick="myCommand()" will merely cause personBean.method to execute. remoteCommand is for when we need to execute something in javascript first, and only then call the bean method. – dennisdeems Jun 12 '15 at 15:46
22

You have a few options. If you are using JSF 2.0 you can build a composite component around these area tags.

The easiest way however would be to invoke a hidden JSF input button.

<h:commandButton id="hdnBtn" actionListener="#{personBean.method}" style="display: none;" />

This will render as an input HTML element on the page that you can access from Javascript and invoke its click event.

onclick="jQuery('#form:hdnBtn').click();"
maple_shaft
  • 10,435
  • 6
  • 46
  • 74
  • Instead of **actionListener**, if we use **action** attribute then it will be easy to redirect in managed beans. [Redirect methodology](https://stackoverflow.com/a/6026401/4067157) is not working with actionListener – Yogi May 24 '17 at 08:41
  • What if me "personBean.method" in the backing bean has parameters (f.e a list) and I would like to pass to it? "#{personBean.method(a_list)"? Is there any possible way to achieve this? – NickAth Apr 25 '19 at 11:37
4

If you want complete ADF Faces solution you can try this:

function doClick(){
   var button = AdfPage.PAGE.findComponentByAbsoluteId("aButton");
   ActionEvent.queue(button,true);
}
Tapas Bose
  • 28,796
  • 74
  • 215
  • 331
4

If you use Seam, Remoting can do this for you: http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/remoting.html

Another approach would be do expose the methods as REST services, and call them from your JavaScript using something like jQuery. Here's a good article on this approach: http://coenraets.org/blog/2011/12/restful-services-with-jquery-and-java-using-jax-rs-and-jersey/

Jeremiah Orr
  • 2,620
  • 1
  • 18
  • 24
  • Not quite what I needed since the application is designed without either approach, but upvoted since they are decent ideas and I wish we could do this as a REST service. – Jason Mar 09 '12 at 12:23
3

This is the most up to date answer, for Java EE 8 (JSF 2.3) use <h:commandScript> this will create a javascript function which will under the hood invoke the jsf backing bean method, and because it's a javascript you can invoke it from your js code

example jsf

<h:form>
<h:commandScript id="submit" 
                 name="jsFunction"
                 action="#{bean.method}"/>
</h:form>

and the js code

</script>
        function invoke()
           {
                jsFunction();
           }
    </script>

for more visit Ajax method invocation

Anas
  • 688
  • 7
  • 24
  • for me the jsFuntion() does return a value, I am planning to store the returned value in a local JS variable but the invocation does not work, any ideas – Ikbel Jun 21 '22 at 13:42
0

If you use primefaces, you can use a hidden input field linked to a managed bean, and you can initialize its value using javascript, for PrimeFaces, the PF function can be used to access a widget variable linked to the hidden input, in this way:

<script>
function codeLoginAddress() {
    PF('wvLoginLat').jq.val( lat1 ); // set in getLocation
    PF('wvLoginLng').jq.val( lng1 )
}
<script>

<p:inputText type="hidden" widgetVar="wvLoginLat" value="#{userSession.lat}" />
<p:inputText type="hidden" widgetVar="wvLoginLng" value="#{userSession.lng}" />

<script>
// at end of page, initialization code
getLocation(); // sets lat1 and lng1
codeLoginAddress(); // sets the value of the widget variables
</script>