我正在寻求帮助,了解如何通过一个表单来创建一个新对象,该表单允许用户选择多个子对象(这些子对象将被预先填充)并可以通过复选框进行选择。
OrderController.java
@RequestMapping(value = { "/order" }, method = RequestMethod.GET)
public String order(ModelMap model) {
List<Exam> exams = examService.findAllExams();
List<Document> documents = documentService.findAllDocuments();
model.addAttribute("exams", exams);
model.addAttribute("documents", documents);
return "order"; // jsp page reference
}
Order.java
@Entity
@Table(name="\"order\"")
public class Order implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "order_id", unique = true, nullable = false)
private Integer id;
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true, nullable = false)
private String uuid;
@Temporal(TemporalType.DATE)
@Column(name = "order_date", unique = true, nullable = false)
private Date orderDate;
@Column(name="order_status", nullable=false)
private String orderStatus;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
private Set<OrderExam> orderExams = new HashSet<OrderExam>(0);
@OneToMany(fetch = FetchType.LAZY, mappedBy = "order")
private Set<OrderDocument> orderDocuments = new HashSet<OrderDocument(0);
//getters & setters
}
OrderExam.java
@Entity
@Table(name="order_exam")
public class OrderExam implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "order_exam_id", unique = true, nullable = false)
private Integer id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "order_id", nullable = false)
private Order order;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "exam_id", nullable = false)
private Exam exam;
@Column(name="exam_amount", nullable=true)
private Integer examAmount;
@Column(name="answer_sheet_amount", nullable=true)
private String answerSheetName;
@Column(name="students_per_csv", nullable=true)
private String studentsPerCSV;
@Column(name="pas", nullable=true)
private Boolean pearsonAnswerSheet;
//getters & setters
}
Exam.java
@Entity
@Table(name="exam")
public class Exam implements Serializable
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "exam_id", unique = true, nullable = false)
private Integer id;
@NotEmpty
@Column(name="name", unique=true, nullable=false)
private String name;
@NotEmpty
@Column(name="code", unique=true, nullable=false)
private String code;
@OneToMany(fetch = FetchType.LAZY, mappedBy = "exam")
private Set<OrderExam> exams = new HashSet<OrderExam>(0);
//getters & setters
}
正如您所看到的,我传递的考试和文档列表将填充带有可用选项的表单(可以在下图中看到(考试))。用户需要能够选择多行,以便单个订单具有多个与之关联的考试和文档。
我的order.jsp在这里发布的内容有点多,但这里是上面图片中显示的部分。
Order.jsp
<form:form method="POST" modelAttribute="order" class="form-horizontal form-label-left">
<c:forEach items="${exams}" var="exam">
<tr>
<th scope="row"><input type="checkbox" class="flat"></th>
<td><input id="middle-name" type="text" name="middle-name" readonly="readonly" value="${exam.name} - ${exam.code}" class="form-control col-md-7 col-xs-12"></td>
<td><input id="middle-name" type="text" name="middle-name" value="0" class="form-control col-md-3 col-xs-12"></td>
<td><input id="middle-name" type="text" name="middle-name" value="0" class="form-control col-md-3 col-xs-12"></td>
<td><input id="middle-name" type="text" name="middle-name" value="0" class="form-control col-md-3 col-xs-12"></td>
<c:choose>
<c:when test="${exam.name == 'Algebra 2 (Common Core)'}">
<th scope="row"><input type="checkbox" class="flat"></th>
</c:when>
<c:otherwise>
<th scope="row"></th>
</c:otherwise>
</c:choose>
</tr>
</c:forEach>
<!-- Other Stuff Goes Here -->
</form:form>
简而言之,有人愿意告诉我如何以上述方式设置表单吗?提前谢谢。
答案 0 :(得分:1)
您的问题有点宽泛,但您可以尝试以下方式。我只参加了考试。文件的负责人将是相同的。
您需要几个新类来捕获提交的表单输入:
订购表单以捕获选择
public class OrderForm{
private List<ExamWrapper> allAvailableExams = new ArrayList<>();
private XOptionPrintWrapper selectedWrapper;
public OrderForm(){
}
//getters and setters
}
考试包装:用选择的&#39;来装饰考试。属性强>
public class ExamWrapper{
private boolean selected;
private Exam exam;
public ExamWrapper(Exam exam){
this.exam = exams;
}
//getters and setters
}
将控制器更改为
public class OrderController{
//Exams model populated by the method below
//moved as we also need it populated on POST
@RequestMapping(value = { "/order" }, method = RequestMethod.GET)
public String order(ModelMap modelMap) {
//only needed on GET so put in model here
List<XOptionPrintWrapper> availableWrappers = //someList;
modelMap.put("availableWrappers", availableWrappers);
return "order";
}
//handles for submit
//model atribute is automatically populated by the framework
@RequestMapping(value = { "/order" }, method = RequestMethod.POST)
public String order(@ModelAttribute("orderForm") OrderForm orderForm) {
//process selected exams
return "nextView";
}
//on get populates the initial model for display
//on post create an instance which the form params will be bound to
@ModelAttribute("orderForm")
public OrderForm getOrderForm(){
OrderForm orderForm = new OrderForm();
List<Exam> exams = examService.findAllExams();
for(Exam exam : exams){
orderForm.getAllAvailableExams.add(new ExamWrapper(exam));
}
return orderForm;
}
}
在JSP中使用Sping支持绑定到索引属性:
<form:form method="POST" modelAttribute="orderForm" class="form-horizontal form-label-left">
<c:forEach items="${orderForm.allAvailableExams}" var="exam" varStatus="status">
<tr>
<th scope="row"><input name="allAvailableExams[${status.index}].selected"
type="checkbox" class="flat"></th>
</tr>
</c:forEach>
<form:select path="selectedWrapper">
<form:options items="${availableWrappers}"
itemValue="somePropertyOfXOptionPrintWrapper "
itemLabel="somePropertyOfXOptionPrintWrapper " />
</form:select>
</form>
我显然无法尝试所有这些,但认为一切都会好起来的。