2014-04-24 18 views
8

In meiner Spring MVC Anwendung muss ich ein dynamisches Fragebogen Formular implementieren: Ich habe N Fragen und für jedes habe ich 3 Optionen.Dynamische Form und Datenbindung mit Spring MVC

Also meiner Seite werde ich so etwas wie dieses:

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

Fragen in einer Datenbank und für die Optionen gespeichert werden, werde ich Radio-Buttons verwenden. Ich werde einen forEach Tag verwendet dynamische Zeilen Creare, aber ich weiß nicht, wie die Daten zu schreiben und zu handhaben ModelAttribute in diesem Szenario Bindung ...

, die eine gute Struktur für mein Modell Attributklasse sein könnte? Ist es möglich, eine Bindung für ein dynamisches Formular mit Spring MVC zu verwenden?

+0

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

+0

Ich würde nur eine POJO-Klasse für die Frage erstellen, und mein Modell Attribut eine einfache Liste dieser Frage Objekte, einfach und leicht zu handhaben ---- myList wäre (oder, wenn Sie nur den Fragetext und die Antwort brauchen, können Sie einfach eine Liste von Arrays oder Karten verwenden) –

Antwort

12

, wie die Daten zu schreiben und zu handhaben ModelAttribute in diesem Szenario Bindung

Sie tun können,

Ich erwäge Question Klasse wie:

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

und Option Klasse wie:

public class Option { 

    private Integer optionKey; 
    private String optionText; 

    //getters and setters 
} 

und eine QuestionsModel Klasse für Form verbindlich wie:

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

und innen Controller-Klasse GET-Handler-Methode, bevölkern Fragen zum Beispiel:

@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"; 
} 

schließlich in jsp Seite Verwendung <form:hidden.. zu alten Werten zu halten, und render Formelemente wie:

<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> 

können Sie erhalten Bindung und das Modell in POST wie:

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

    return "redirect:/"; 
} 
2

Diese Klasse ist mein Modell Attribut:

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

    // set + get 
} 

Und:

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

    // set+ get 

} 

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

    // set + get 
} 

ich bevölkern questions Liste, bevor ich setzen es in Modell.

In meiner Seite verwende ich diesen Code:

<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> 

dieses Formular Posting ich eine voll bestückte questionnaire Instanz in meinem Controller erhalten.

HINWEIS Ich fand this post sehr hilfreich, um mein Problem zu lösen.

+0

Der Link "Ich fand diesen Beitrag sehr hilfreich" ist kaputt. –