How to call JSF backing bean method only when onclick/oncomplete/on... event occurs and not on page load

I have two image buttons:

<div class="sidebarOptions">
    <input type="image" src="images/homeButton.jpg" onclick="#{home.setRendered(1)}"/>
</div>
<div class="sidebarOptions">
    <input type="image" src="images/memberButton.jpg" onclick="#{home.setRendered(2)}"/>
</div>

However, the both methods are immediately invoked when the page loads with values 1 and 2. Also when I click it, the both methods are invoked.

How can I achieve the desired functionality of only calling the bean method when the image button is actually clicked?


This approach will not work. You seem to be confusing/mixing the basic web development concepts of the "server side" and "client side" and to be misunderstanding the role of JSF and EL.

JSF is a server side language which runs on the webserver upon a HTTP request and produces HTML/CSS/JS code which get returned with the HTTP response. All EL expressions in form of ${} and #{} will be executed in the server side during generating the HTML output. JavaScript is a client side language which runs on the webbrowser and works on the HTML DOM tree. The HTML onclick attribute should specify a JavaScript function which will be executed in the client side on the particular HTML DOM event.

In order to invoke a JSF managed bean method, you need the action or *listener attribute. JSF provides components to generate the desired HTML and specify the desired ajax actions which would change the server side state. An <input type="image"> can be generated using a <h:commandButton image>. A bean method can be invoked by the action attribute of that component. That component can be ajaxified by embedding the <f:ajax> tag.

So, the following should do it for you:

<h:form>
  <div class="sidebarOptions">
    <h:commandButton image="images/homeButton.jpg" action="#{home.setRendered(1)}">
      <f:ajax execute="@this" render=":sidebar" />
    </h:commandButton>
  </div>
  <div class="sidebarOptions">
    <h:commandButton image="images/memberButton.jpg" action="#{home.setRendered(2)}">
      <f:ajax execute="@this" render=":sidebar" />
    </h:commandButton>
  </div>
</h:form>

<!-- The below is just a guess of what you're really trying to achieve. -->
<h:panelGroup id="sidebar" layout="block">
  <h:panelGroup rendered="#{home.rendered eq 1}">
    Home
  </h:panelGroup>
  <h:panelGroup rendered="#{home.rendered eq 2}">
    Member
  </h:panelGroup>
</h:panelGroup>

See also:

  • Differences between action and actionListener
  • How to invoke a managed bean action method in on* attribute of a JSF component
  • How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?