我有这种表格映射:
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
(元组的元素)相关联。
但是,为了让startSchedule
方法都可以使用所需的元素(endSchedule
和checkForEndScheduleConsistency
),我无法直接在嵌套上应用verifying
方法元组的元素名为endSchedule
。相反,我必须在整个元组中应用一个以包含startSchedule
变量,如代码段所示。
缺点是错误未映射到endSchedule
而是映射到schedule
(我的HTML表单中没有任何内容),因此当出现不一致的计划时,屏幕上不会显示任何内容
因此,我必须使用此“解决方法”来使用Form
的{{1}}方法来实现我的要求:
withError
=>非常丑陋和反干。
有没有办法在元组上应用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
上。
答案 0 :(得分:2)
根据documentation的说法,最好的解决方案可能是在您自己制作字段时替换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>
这样您就可以手动将错误引用替换为正确的元素。不是很好,但你应该能够从中创建一个可重复使用的标签。
答案 1 :(得分:1)
最好的解决方案是将全局(计划)“错误”键精确到更具体的生成输入,这里是schedule.endSchedule
输入:
@inputText(hobbyForm("schedule.endSchedule"), 'id -> "schedule.endSchedule", '_error -> hobbyForm.error("schedule")
注意部分:'_error -> hobbyForm.error("schedule")