简体   繁体   中英

primefaces how to retrieve changed values from picklist

i have implemented the following picklist:

<p:pickList id="pickList" value="#{reportConfiguratorBean.dualListVars}" var="cRVariable" itemValue="#{cRVariable}" itemLabel="#{cRVariable.varName}" converter="#{cRImageTypeConverter}" immediate="true" rendered="true" >
    <f:facet name="sourceCaption">Available Variables</f:facet>
    <f:facet name="targetCaption">Associated Variables</f:facet>                
</p:pickList>                       
<f:facet name="footer"> 
    <p:commandButton id='varassociate' action="#{reportConfiguratorBean.setAssocImTypVariables()}" value='Associate' process="@this,pickList" />
</f:facet>

Picklist is populated correctly (using getAssocImTypVariables() from database). But my ISSUE is that i can not capture the changed picklist values of a user alters the source and target lists. I am trying to capture the changes using a commandButton method "setAssocImTypVariables" as follows:

public void setAssocImTypVariables() {      
    System.out.println(">>>>>>>>>>>>>>> entered");          
    List<CRVariable> sourceVariables = this.dualListVars.getSource();
    List<CRVariable> targetVariables = this.dualListVars.getTarget();       

    System.out.println(dualListVars.getSource());
    System.out.println(dualListVars.getTarget());

    for (CRVariable sourceVariable:sourceVariables) {
        System.out.println(">>>>>>>>>>>>> I am a source variable: " + sourceVariable.getVarName());
    }       
    for (CRVariable targetVariable:targetVariables) {
        System.out.println(">>>>>>>>>>>>> I am a target variable: " + targetVariable.getVarName());
    }       
    }

So if for example i have a picklist with INITIAL source = (Obj1,Obj2,Obj3,Obj5,Obj7) and target = (Obj4,Obj6), i move "Obj1" from source to target BUT in my console i get:

--------- entered [] []

So my dualListVars (source and target) is not populated! I have two empty lists for source and target...

So my method CAN NOT perceive picklist's changes... Any ideas? I am new to java + primefaces so it could be something really fundamental :(

I am also attaching the method getAssocImTypesOnLoad():

public void getAssocImTypesOnLoad() {               
    Long imTypeId = Long.parseLong(virtualId);      
    List<CRVariable> source;
    List<CRVariable> target;        
    Session session = HibernateUtil.getSessionFactory().openSession();
    Transaction tx = null;      
    try 
    {
        tx = session.beginTransaction();            
        String hq3 = "select distinct v from CRVariable v join v.crimagetypes t where t.id in (:itid)";
        Query query3 = session.createQuery(hq3);
        query3.setParameter("itid",imTypeId);
        target = query3.list();
        String hq4 = "select v FROM CRVariable v WHERE v.id not in (" +
                "select distinct v1.id " +
                "from CRVariable v1 " +
                "join v1.crimagetypes t2 " +
                "where t2.id in (:itid))";
        Query query4 = session.createQuery(hq4);
        query4.setParameter("itid",imTypeId);
        source = query4.list();
        dualListVars = new DualListModel<CRVariable>(source, target);
        tx.commit();
    } 
    catch (Exception e) 
    {
        if (tx != null) 
        {
            e.printStackTrace();
        }
    } 
    finally 
    {
       session.close();
    }
}

Take a closer look to the primefaces showcase : Primefaces picklist

Call the dualListVars directly. #{reportConfiguratorBean.dualListVars} is resolved to reportConfiguratorBean.getDualListVars() since dualListVars is a property (eg. a property with a getter and a setter).

<p:pickList id="pickList" value="#{reportConfiguratorBean.dualListVars}" var="cRVariable" itemValue="#{cRVariable}" itemLabel="#{cRVariable.varName}" converter="#{cRImageTypeConverter}" immediate="true" rendered="true" >
    <f:facet name="sourceCaption">Available Variables</f:facet>
    <f:facet name="targetCaption">Associated Variables</f:facet>                
</p:pickList> 

The action attribute is meant for business logic. You can catch here the source and target list. The process attribute tell JSF which components to process. In your case, you want the component picklist and commandButton to be processed. You can also process the whole form with process="@form" .

<p:commandButton id='varassociate' action="#{reportConfiguratorBean.readMyAssocImTypVariables}" value='Associate' ajax='false' process="@this,pickList" immediate="true" />

The readMyAssocImTypVariables function :

 public void readMyAssocImTypVariables() {      
    List<CRVariable> sourceVariables = this.dualListVars.getSource();
    List<CRVariable> targetVariables = this.dualListVars.getTarget();       
    for (CRVariable sourceVariable:sourceVariables) {
        System.out.println(">>>>>>>>>>>>> I am a source variable: " + sourceVariable.getVarName());
    }       
    for (CRVariable targetVariable:targetVariables) {
        System.out.println(">>>>>>>>>>>>> I am a target variable: " + targetVariable.getVarName());
     }       
  }

Unrelated : Do NOT put business logic into getters/setters ! They are called multiple time by JSF.

Why are you using immediate=true attribute on the commandButton ?

If I remember it correctly, according to an article from balusC check it out here an immediate=true on a commandButton should skip the apply model to values phase .

Maybe that is the reason, why your model is not updated?

(Just a guess by looking at the code - I have not reproduced this.)

a running picklist example picklist.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">


<h:head></h:head>

<h:body>
<h:form>
    <h3>Basic PickList</h3>
    <p:pickList value="#{pickListBean.cities}" var="city"
        itemLabel="#{city}" itemValue="#{city}" />
<p:commandButton  value="Submit" action="#{pickListBean.displayList}" />    


</h:form>

</h:body>
</html>   

PickListBean.java

import java.util.ArrayList;
import java.util.List;

import javax.faces.bean.ManagedBean;
import org.primefaces.model.DualListModel;

@ManagedBean
public class PickListBean {

   private DualListModel<String> cities;

   public PickListBean() {

  //Cities
  List<String> citiesSource = new ArrayList<String>();
  List<String> citiesTarget = new ArrayList<String>();

  citiesSource.add("Istanbul");
  citiesSource.add("Ankara");
  citiesSource.add("Izmir");
  citiesSource.add("Antalya");
  citiesSource.add("Bursa");
//  citiesTarget.add("T1");


  cities = new DualListModel<String>(citiesSource, citiesTarget);
   }

   public DualListModel<String> getCities() {
      return cities;
   }
   public void setCities(DualListModel<String> cities) {
      this.cities = cities;
   }
   public void displayList(){

     System.out.println("values in list are" +cities.getTarget());


   }


}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM