java - jsf commandbutton action not working ajax -


this question has answer here:

i've got page, have 2 forms on. second form loaded (rendered) ajax. problem is, when button of next form pressed, page reloads itself, not calling method specified in 'action'.

xhtml

<?xml version='1.0' encoding='utf-8' ?> <!doctype composition public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"                 template="./../web-inf/employeetemplate.xhtml"                 xmlns:h="http://java.sun.com/jsf/html"                 xmlns:f="http://java.sun.com/jsf/core"                 xmlns="http://www.w3.org/1999/xhtml">      <ui:define name="content">         finding user ...         <h:form id="mainform">             <h:inputtext id="userid" value="#{efinduser.userid}" />             <h:commandbutton value="render!" action="#{efinduser.finduser}" >                 <f:ajax event="action" execute="userid" render="@all" />             </h:commandbutton>         </h:form>                  <h:panelgroup id="result">             <h:panelgroup layout="block" rendered="#{efinduser.notfound}" style="color:red">                 user not found             </h:panelgroup>              <h:form>                 <h:panelgroup layout="block" rendered="#{efinduser.responserendered}" >                      <h:inputhidden value="#{efinduser.user}" />                     <table>                         <tr>                             <td>name</td> <td>#{efinduser.user.name}</td>                         </tr>                         <tr>                             <td>balance:</td> <td>#{efinduser.user.account.balance}</td>                         </tr>                          <tr>                             <td><h:commandbutton value="update balance" action="#{efinduser.process()}" /></td>                         </tr>                     </table>                   </h:panelgroup>             </h:form>                                 </h:panelgroup>        </ui:define>  </ui:composition> 

backing bean

/*  * change template, choose tools | templates  * , open template in editor.  */ package backingbeans;  import entities.user; import java.io.serializable; import java.util.random; import javax.faces.bean.managedbean; import javax.faces.bean.viewscoped; import javax.inject.inject; import javax.validation.constraints.notnull; import stateless.employeefacade;  /**  *  * @author martin  */     @managedbean(name="efinduser")     @viewscoped     public class efindusermanagedbean implements serializable{         private static final long serialversionuid = -7106162864352727534l;         private boolean responserendered = false;         private boolean notfound = false;         @notnull         private long userid;         private user user;          @inject         private eupdatebalancemanagedbean updatebalance;          @inject         private employeefacade employeefacade;          /**          * creates new instance of efindusermanagedbean          */          public efindusermanagedbean() {         }          public void finduser() {             if(new random().nextdouble() < 0.3) {                 notfound = true;                 responserendered = false;             } else {                 notfound = false;                 responserendered = true;                 user = employeefacade.getuserbyid(3l);             }          }         public boolean isresponserendered() {             return responserendered;         }          public void setresponserendered(boolean responserendered) {             this.responserendered = responserendered;         }      public boolean isnotfound() {         return notfound;     }      public void setnotfound(boolean notfound) {         this.notfound = notfound;     }      public long getuserid() {         return userid;     }      public void setuserid(long userid) {         system.out.println("blah");         this.userid = userid;     }      public user getuser() {         return user;     }      public void setuser(user user) {         system.out.println("setting user");         this.user = user;     }       public string process() {         updatebalance.setuser(user);         system.out.println("process");         return "/employee/updatebalance.xhtml?faces-redirect=true";     }      } 

when click first 'render!'-labeled button, works charm. second form loaded , ready work. when click next 'update balance'-labeled button, page reloads shouldn't, of course. should redirect "/employee/updatebalance". or should @ least call process method.

thanks lot

edit: @balusc right, answer in previous question

the culprit can found in <h:inputhidden> tag of second form:

<h:form>     <h:panelgroup layout="block" rendered="#{efinduser.responserendered}" >         <h:inputhidden value="#{efinduser.user}" />     </h:panelgroup> </h:form> 

most bound value, efinduser.user of type user , when submit form jsf doesn't know how assign string representation of user user object.

hence, there conversion error, in case action method not called, according jsf lifecycle. additionally, have known if had <h:messages> in view.

what can done following:

  1. assign converter input <h:inputhidden value="#{efinduser.user}" converter="userconverter"/> @facesconverter implemented. more details can found here.
  2. bind <h:inputhidden> string, no converter needed: <h:inputhidden value="#{efinduser.user.usernickname}"> or integer in similar way.

Comments