【问题标题】:How to represent a dynamic form with Play forms?如何用 Play 表单表示动态表单?
【发布时间】:2015-02-08 13:12:03
【问题描述】:

我有一个类似于测验/问卷类型设计的表格。

所以说页面是一个测验,它会在页面上显示一个动态数量的问题,每个问题都会有一个复选框选项列表(用户可以选择1+个复选框)。

我如何在游戏中表现这种类型的形式?

case class Quiz(id: Int, name: String)
case case Question(id: Int, quizId: Int, title: String)
case class QuestionOption(id: Int, questionId: Int, name:String)

所以你有一个测验,有很多问题。而且每个问题都有多个 QuestionOptions。

所以表格应该是这样的:

case class QuizForm(quiz: Quiz, questions: List[Question], options: List[QuestionOption])

对于每个问题,您可以选择 1 个或多个 QuestionOption。

【问题讨论】:

  • 你能提供一个Form应该绑定到的类的例子吗?
  • @m-z 我更新了问题,希望能解决问题。

标签: scala playframework


【解决方案1】:

我会将Questions 嵌套在Quiz 中,将QuestionOptions 嵌套在Question 中。这最终可能会使它更加紧凑。

case class Quiz(id: Int, name: String, questions: List[Question])
case class Question(id: Int, quizId: Int, title: String, options: List[QuestionOption])
case class QuestionOption(id: Int, questionId: Int, name: String)

Form 的可能实现将使用 lists 的 mapping

val quizForm: Form[Quiz] = Form {
    mapping(
        "id" -> number,
        "name" -> nonEmptyText,
        "questions" -> list(mapping(
            "id" -> number,
            "quizId" -> number,
            "title" -> nonEmptyText,
            "options" -> list(mapping(
                "id" -> number,
                "questionId" -> number,
                "name" -> nonEmptyText
            )(QuestionOption.apply)(QuestionOption.unapply))
        )(Question.apply)(Question.unapply))
    )(Quiz.apply)(Quiz.unapply)
}

最冗长的部分是 HTML 表单,它需要包含所有这些字段。以下是表单将发送的数据示例(一个问题,多个答案)。

val data = Map(
    "id" -> "1",
    "name" -> "My Quiz",
    "questions[0].id" -> "1",
    "questions[0].quizId" -> "1",
    "questions[0].title" -> "What?",
    "questions[0].options[0].id" -> "1",
    "questions[0].options[0].questionId" -> "1",
    "questions[0].options[0].name" -> "red",
    "questions[0].options[1].id" -> "2",
    "questions[0].options[1].questionId" -> "1",
    "questions[0].options[1].name" -> "green",
    "questions[0].options[2].id" -> "4",
    "questions[0].options[2].questionId" -> "1",
    "questions[0].options[2].name" -> "blue"
)

每个问题元数据/答案的name 字段都需要具有将它们绑定在一起的唯一索引。这是一个粗略的例子:

<input type="hidden" name="id" value="1">
<input type="hidden" name="name" value="My Quiz">

<input type="hidden" name="questions[0].id" value="1">
<input type="hidden" name="questions[0].quizId" value="1">
<input type="hidden" name="questions[0].title" value="What?">

<input type="hidden" name="questions[0].options[0].id" value="1">
<input type="hidden" name="questions[0].options[0].questionId" value="1">
<input type="checkbox" name="questions[0].options[0].name" value="red">

<input type="hidden" name="questions[0].options[1].id" value="2">
<input type="hidden" name="questions[0].options[1].questionId" value="1">
<input type="checkbox" name="questions[0].options[1].name" value="green">

<input type="hidden" name="questions[0].options[2].id" value="3">
<input type="hidden" name="questions[0].options[2].questionId" value="1">
<input type="checkbox" name="questions[0].options[2].name" value="blue">

<input type="hidden" name="questions[0].options[3].id" value="4">
<input type="hidden" name="questions[0].options[3].questionId" value="1">
<input type="checkbox" name="questions[0].options[3].name" value="orange">

我们可以通过删除一些标题/名称字段并在Form 中忽略它们来缩小它,因为它们对持久性无关紧要。但这很快就会变得相当冗长。

此时我通常会放弃 Forms 并使用纯 JavaScript,因为 JSON 更易于处理(在我看来,可读性更强)。

【讨论】:

  • 非常感谢。您会使用表单输入助手生成“questions[0].options[1].questionId 名称吗?
  • 我对播放表单助手不是很熟悉。这可能取决于您如何生成 HTML,但我想在 questions 上使用 zipWithIndex 并循环通过它(在 options 上使用内部循环)可以解决问题。
  • 我也可以在回发中,遍历我的问题和选项,然后查找 request.queryString 并按照我猜的方式进行操作。
猜你喜欢
  • 1970-01-01
  • 2012-06-16
  • 2020-11-04
  • 2011-12-03
  • 2011-09-03
  • 2022-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多