3

我有这个表格映射:

val myElement = Form(
    mapping(
      "title" -> nonEmptyText,
      "schedule" ->
        tuple("startSchedule" -> jodaDate("dd/MM/yyyy HH:mm"),
          "endSchedule" -> jodaDate("dd/MM/yyyy HH:mm"))
          .verifying(MyValidator().checkForEndScheduleConsistency("error.schedule")),
    )(MyElement.apply)(MyElement.unapply)
  )

MyElement班级:

case class MyElement(title: String, schedule: (Datetime, Datetime))

MyValidator班级:

def checkForEndScheduleConsistency(errorMsg: String) =
    Constraint[(DateTime, DateTime)]("constraint.schedule", errorMsg) {
      schedule =>
        MyDomainValidator().checkForEndScheduleConsistency(schedule._1, schedule._2, Messages(errorMsg)) match {
          case Success(s) => Valid
          case Failure(f) => Invalid(ValidationError("custom error string from `f`"))
        }
    }

schedule.endSchedule要求:如果调度根据MyValidator对象不一致,则必须将错误消息关联到字段(元组的元素)。

但是,为了使方法所需的元素 (startScheduleendSchedule) 都可用checkForEndScheduleConsistency,我不能verifying直接在嵌套元组的名为 的元素上应用方法endSchedule。相反,我必须在整个元组上应用一个以包含startSchedule变量,如代码片段所示。

缺点是错误不是映射到endSchedule而是映射到schedule(这不代表我的 HTML 表单中的任何内容),因此当出现不一致的计划时,屏幕上不会显示任何内容。

因此,我必须使用这个“解决方法”来使用Form'swithError方法来实现我的要求:

def create = Action {
    implicit request =>
      myForm.bindFromRequest.fold(
        myFormWithErrors => {
          myFormWithErrors.error("schedule") match { //check for the presence of potential schedule error
          case Some(e) => {
            BadRequest(views.html.create_element("Create an element", myFormWithErrors.withError("schedule.endSchedule", Messages("error.schedule"))))
          }
          case _ => BadRequest(views.html.create_element("Create an element", myFormWithErrors))
        }
        },
        myForm => {
          treatSubmittedMyForm(myForm)
        }
      )
  }

=> 非常丑陋和抗干燥。

有没有办法应用于verifying元组,尽管如此,将错误消息应用于嵌套元组的元素?就我而言,在endSchedule.

4

2 回答 2

2

根据文档,最好的解决方案可能是在通过您自己的制作渲染字段时替换 Play 提供的默认助手:

@(elements: helper.FieldElements)

<div class="@if(elements.hasErrors) {error}">
    <label for="@elements.id">@elements.label</label>
    <div class="input">
        @elements.input
        <span class="errors">@elements.errors.mkString(", ")</span>
        <span class="help">@elements.infos.mkString(", ")</span> 
    </div>
</div>

这样,您可以手动将错误引用替换为正确的元素。不是很好,但您应该能够从中创建可重用的标签。

于 2013-03-04T12:07:04.947 回答
1

最好的解决方案是将全局(调度)“错误”键直接精确到更具体的生成输入中,这里是schedule.endSchedule输入:

@inputText(hobbyForm("schedule.endSchedule"), 'id -> "schedule.endSchedule", '_error -> hobbyForm.error("schedule")

注意部分:'_error -> hobbyForm.error("schedule")

于 2013-03-10T08:02:06.223 回答