Search code examples
jsfuirepeatselectmanycheckbox

ui:repeat h:selectManyCheckbox i can t get values inside a list


I'm working on a JSF 2.2 project , jboss 8.x

I created a dynamic form only with selectManyCheckbox.

I have the following code :

<h:form>



                  <table border="5">


 <ui:repeat var="question" value="#{beanQuiz.traninigee.questions}">
      <tr> #{question.question} </tr>

      <tr>
        <h:selectManyCheckbox value="#{beanQuiz.questionAnswers[question]}"
                                      converter="javax.faces.Integer">
                    <f:selectItems  var="response"
                                    value="#{question.responses}"
                                    itemLabel="#{response.reponse}"
                                    itemValue="#{response.responseId}" />
                </h:selectManyCheckbox>
            </tr>
        </ui:repeat>

                </table>
 <h:commandButton value="Submit" action="result" styleClass="btn btn-success btn-cons m-b-10" />
        <h:commandButton value="Reset" type="reset"  styleClass="btn btn-warninig btn-cons m-b-10"/>

        </h:form>

selectedArticles is list of entities.

I see on the web the value of a selectManyCheckbox can point to a String[] or List. With this code the selectedArticles don't contains all the checked value, only the latest checked group.

What should i do for getting all the checked values ?

@ManagedBean
@SessionScoped
public class beanQuiz implements Serializable{


    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @EJB
    private trainingServiceLocal local;

    private List<Integer> selectedreponses;

    private List<Training> trainings;

    private Training traninigee=new Training();



public String redirectquiz(int idt){

    traninigee=local.findtrainingbyId(idt);



    return "quiz";
}


    public List<Integer> getSelectedreponses() {
        return selectedreponses;
    }

    public void setSelectedreponses(List<Integer> selectedreponses) {
        this.selectedreponses = selectedreponses;
    }

    public int getInc() {
        return inc;
    }

    public void setInc(int inc) {
        this.inc = inc;
    }


    private int inc;

    public Training getTraninigee() {
        return traninigee;
    }

    public void setTraninigee(Training traninigee) {
        this.traninigee = traninigee;
    }

    @PostConstruct
    public void init() {
        inc=0;
        trainings = local.findAlltrainings();


        //traninigee=local.findtrainingbyId(1);
        //System.out.println("-----||||||||||||----**---"+traninigee);




    }


//  private static Map<String,Object> color2Value;
//  static{
//      color2Value = new LinkedHashMap<String,Object>();
//      for()
//      color2Value.put("Color2 - Red", "Red"); //label, value
//      
//  }





    public List<Training> getTrainings() {
        return trainings;
    }




    public void setTrainings(List<Training> trainings) {
        this.trainings = trainings;
    }

my class diagram is like that : i ve got a class of trainings that contrains list of question (onetomany) my class question contains list of reponses (one to many ) and my class responses is a simple class that contains the response as string im using jpa

Classe Training 
{
    @OneToMany(fetch = FetchType.EAGER,mappedBy="training")
    private List<Question> questions;
}



classe Question 

{

@OneToMany(mappedBy="question",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
    private List<Respons> responses;

}




classe response {
@Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int responseId;
    private Boolean isValid;

    //bi-directional many-to-one association to Question

}

my list quiz expl .xhtml

<ui:repeat var="cat" value="#{beanQuiz.trainings}">




<h:commandButton action="#{beanQuiz.redirectquiz(cat.trainingId)}" value="#{cat.name} " styleClass="btn btn-block btn-success">




</h:commandButton>





<br></br>

</ui:repeat>

and my result page where im going to show the result of checked selectboxes

      <h:form>

           <p>selected responses: </p>

            <br/>

            <p>#{}</p>

 <c:forEach items="#{beanQuiz.questionAnswers.values()}" var="res">


                <p> #{res}</p>
<p>------------</p>
                <br></br>

</c:forEach>
        </h:form>

Solution

  • Ok, so here is what you have to do:

    a) Modify the Backing Bean by removing the List and replacing it with a Map which will pair up questions to the list of answers:

    @ManagedBean
    @SessionScoped
    public class BackingBean implements Serializable{
    
    
    @EJB
    private wagentServiceLocal local;
    
    private Training training=new Training();
    
    private Map<Question, List<Integer>> questionAnswers
            = new HashMap<Question, List<Integer>>();
    
     // When setting up the training to be used in the multiChebox tag
     // set up the map of question to list of chosen responses.
     public String redirectquiz(int idt){
    
         training=local.findtrainingbyId(idt);
    
         for(Question question: traninigee.getQuestions()){
               questionAnswers.put(question, new ArrayList<Integer>());            
         }
    
         return "quiz";
     }
    
    public Map<Question, List<Integer>> getQuestionAnswers() {
        return questionAnswers;
    }
    
    public void setQuestionAnswers(Map<Question
                  , List<Integer>>     questionAnswers) {
        this.questionAnswers = questionAnswers;
    }
    

    b) You modify the selectManyCheckBox to use a separate List for each of the Questions:

    <ui:repeat var="question" value="#{beanQuiz.training.questions}">
          <tr >#{question.question} :
          </tr>
          <tr>
            <h:selectManyCheckbox value="#{beanQuiz.questionAnswers[question]}"
                                          converter="javax.faces.Integer">
                        <f:selectItems  var="response"
                                        value="#{question.responses}"
                                        itemLabel="#{response.name}"
                                        itemValue="#{response.id}" />
                    </h:selectManyCheckbox>
                </tr>
            </ui:repeat>
    

    Thanks to that, each group of checkboxes will have its own List object and will not be interfered by other groups. You just have to change your logic on the way you extract the results for each of the question or use 'questionAnswers.values();', iterate and combine all the responses regardles of the question.

    Hope that helps