2014-04-24 83 views
8

在我的Spring MVC應用程序中,我需要實現一個動態問卷形式:我有N個問題,每個問題有3個選項。動態表單和與Spring MVC的數據綁定

所以在我的網頁我有這樣的事情:

| Question 1 | 1 | 2 | 3 | 
| Question 2 | 1 | 2 | 3 | 
| Question 3 | 1 | 2 | 3 | 
| ...   | 1 | 2 | 3 | 
| Question N | 1 | 2 | 3 | 

問題都存儲在一個數據庫和我將使用單選按鈕的選項。 我將使用一個forEach標籤creare動態行,但我不知道如何發佈數據和處理ModelAttribute在這種情況下綁定...

這可能是我的模型結構良好屬性類?是否有可能使用Spring MVC的動態表單綁定?

+0

[AutoPopulatingList](http://docs.spring.io/spring/docs/3.0。x/api/org/springframework/util/AutoPopulatingList.html) – GriffeyDog

+0

我只想爲Question創建一個POJO類,而我的模型屬性將是這些Question對象的一個​​簡單列表,簡單且易於處理---- myList (或者,如果你只是需要問題文本和答案,你可以使用數組或地圖列表) –

回答

12

如何發佈數據和處理的ModelAttribute在這種情況下

你可以做結合,

我正在考慮Question類,如:

public class Question { 
    private String question; 
    private Map<Integer,Option> optionMap; 
    private Integer selectedOptionKey; 
     //getters and setters 
} 

Option類,如:

public class Option { 

    private Integer optionKey; 
    private String optionText; 

    //getters and setters 
} 

和一個QuestionsModel類形式樣結合:

public class QuestionsModel { 
    private Map<Integer, Question> questionMap; 
    //getters and setters 
} 

和內部控制類GET處理方法,填充例如問題:

@RequestMapping(method=RequestMethod.GET) 
    public String index(Model model){     
    Option optionA = new Option(1, "A"); 
    Option optionB = new Option(2, "B"); 
    Option optionC = new Option(3, "C"); 

    Map<Integer, Option> optionMap = new HashMap<Integer, Option>(); 
    optionMap.put(optionA.getOptionKey(),optionA); 
    optionMap.put(optionB.getOptionKey(),optionB); 
    optionMap.put(optionC.getOptionKey(),optionC); 

    Question question1 = new Question("A Q", optionMap, 1); 
    Question question2 = new Question("B Q", optionMap, 1); 
    Question question3 = new Question("C Q", optionMap, 1); 
    Map<Integer, Question> questionMap = new HashMap<Integer, Question>(); 
    questionMap.put(1, question1); 
    questionMap.put(2, question2); 
    questionMap.put(3, question3); 

    model.addAttribute("questionsModel", new QuestionsModel(questionMap)); 

    return "index"; 
} 

終於在JSP頁面中使用<form:hidden..保留舊值,並渲染表單元素:

<c:url value="/questionPost" var="postUrl"/> 

<form:form action="${postUrl}" modelAttribute="questionsModel" method="post"> 
    <table> 
    <tr> 
     <th>Question</th> 
     <th>Options</th>   
    </tr> 
    <c:forEach items="${questionsModel.questionMap}" var="currQue" varStatus="queIndex"> 
     <tr> 
      <td> 
       <form:hidden path="questionMap[${queIndex.count}].question"/> 
       <label>Question:</label><c:out value="${currQue.value.question}"/><br/> 
      </td> 
      <td> 
      <c:forEach items="${currQue.value.optionMap}" var="opt" varStatus="optionIndex"> 
       <form:hidden path="questionMap[${queIndex.count}].optionMap[${optionIndex.count}].optionText"/> 
       <form:hidden path="questionMap[${queIndex.count}].optionMap[${optionIndex.count}].optionKey"/> 

       <form:radiobutton path="questionMap[${queIndex.count}].selectedOptionKey" 
        value="${opt.value.optionKey}" label="${opt.value.optionText}"/> 

      </c:forEach> 

      </td> 
     </tr> 
    </c:forEach> 
    </table> 
    <input type="submit"/> 
</form:form> 

即可領取綁定和模型POST,如:

@RequestMapping(value="/questionPost", method=RequestMethod.POST) 
public String indexPost(@ModelAttribute("questionsModel") QuestionsModel questionModel, BindingResult result){ 
    System.out.println(questionModel.getQuestionMap()); 

    return "redirect:/"; 
} 
2

這個班是我模型屬性

public class Questionnaire { 
    private List<Question> questions = new ArrayList<>(); 
    private List<Answer> answers = new ArrayList<>(); 

    // set + get 
} 

和:

public class Question { 
    private int id; 
    private String text; 

    // set+ get 

} 

public class Answer { 
    private int questionId; 
    private int value; 

    // set + get 
} 

我填充questions名單之前,我把它變成模型。

在我的網頁我用這個代碼:

<c:forEach items="${questionnaire.questions}" var="question" 
    varStatus="gridRow"> 
    <div> 
    ${question.text} 
     <s:bind path="questionnaire.answers[${gridRow.index}].questionID"> 
      <input type="hidden" name="${status.expression}" 
       id="${status.expression}" value="${question.id}" /> 
     </s:bind> 
     <s:bind path="questionnaire.answers[${gridRow.index}].value"> 
      <sf:radiobuttons path="${status.expression}" 
       items="${radio_button_options}" /> 
     </s:bind> 
    </div> 
</c:forEach> 

發佈這種形式我在控制器得到完全填充的questionnaire實例。

注意我發現this post非常有助於解決我的問題。

+0

鏈接「我發現這篇文章非常有幫助」已打破。 –