编辑现有对象时,在Play Framework 2 Form中渲染字段

时间:2014-07-22 14:58:29

标签: forms scala playframework crud playframework-2.1

这似乎是一个非常基本的问题。我正在使用Play Framework 2.1.5与Scala 2.10开发一个CRUD应用程序(将来会有更多)。我也在使用Twitter Bootstrap 3.2.0。当我尝试更新对象时,我无法获取模板来呈现表单的值。

我正沿着这本书Play for Scala。我已经可以创建一个新对象了。现在我希望能够编辑对象。

Product域对象使用Squeryl映射:

case class Product(ean: Long, name: String, description: String) extends KeyedEntity[Long]

随附的Person对象具有相应的CRUD功能。 Product.findByEan(ean)是一个简单的按字段查询搜索,返回Option[Person]

Persons控制器具有Form[Person]映射:

private val productForm = Form(mapping(
    "ean" -> longNumber.verifying("validation.ean.duplicate", Product.findByEan(_).isEmpty),
    "name" -> nonEmptyText,
    "description" -> nonEmptyText)(Product.apply)(Product.unapply))

在我的routes

GET        /products                         controllers.Products.list
POST       /products                         controllers.Products.save
GET        /products/new                     controllers.Products.newProduct
GET        /products/$ean<\d{13}>            controllers.Products.show(ean: Long)
GET        /products/$ean<\d{13}>/edit       controllers.Products.edit(ean: Long)

Products.edit路线应使用其ean字段加载产品,并使用找到的产品预先填写编辑表单。

def edit(ean: Long) = Action { implicit request =>
    Product.findByEan(ean) match {
        case Some(product) =>
            Logger.info("found product: ean = " + ean)
            val form = productForm.fill(product)
            Logger.info(form.toString)
            Ok(views.html.products.editProduct(form))
        case None => Redirect(routes.Products.list)
    }
}

我知道我已成功检索到该对象,因为Logger消息在播放控制台中清楚地显示了这一点。

呈现表单的editProducts模板是:

@(productForm: Form[Product])(implicit flash: Flash, lang: Lang)
@import helper._
@import helper.twitterBootstrap._

@productsLayout(Messages("products.form")) {
    <h2>@Messages("products.form")</h2>

    @helper.form(action = routes.Products.save()) {
        <fieldset>
            <legend>
                @Messages("products.details", Messages("products.edit"))
            </legend>
            @helper.inputText(productForm("product.ean"))
            @helper.inputText(productForm("product.name"))
            @helper.textarea(productForm("product.description"))
        </fieldset>
        <p><input type="submit" class="btn primary" value='@Messages("products.edit.submit")'</p>
   }
}

问题在于,当我尝试编辑我的Product对象时,此表单模板不会使用检索到的产品对象中的<input>属性预填充value标记。当我尝试创建一个对象但提交一个包含验证错误的表单时,相同的模板工作正常。

  1. 还有其他人遇到过这个问题吗?
  2. twitterBootstrap helper是否假定Bootstrap 2而不是Bootstrap 3?

1 个答案:

答案 0 :(得分:1)

广告。 1

您的问题与您引用表单字段名称的方式有关。您不应该将映射对象名称作为前缀。

@helper.inputText(productForm("ean"))
@helper.inputText(productForm("name"))
@helper.textarea(productForm("description"))

更多信息

值得记住,通过提供映射中指定的名称来访问表单字段。指定的字段名称不必与相应的案例类字段名称匹配。如果您的映射看起来像这样

private val productForm = Form(mapping(
    "id" -> longNumber.verifying("validation.ean.duplicate", Product.findByEan(_).isEmpty),
    "full-name" -> nonEmptyText,
    "desc" -> nonEmptyText)(Product.apply)(Product.unapply))

您可以通过这种方式访问​​模板中的字段

@helper.inputText(productForm("id"))
@helper.inputText(productForm("full-name"))
@helper.textarea(productForm("desc"))

广告。 2

虽然如果您点击 Twitter引导程序字段构造函数部分中的 Twitter Bootstrap 链接,字段帮助程序工作正常,您将被重定向到Bootstrap v2.3.2主页,我想这个助手是为以前的版本设计的。

http://www.playframework.com/documentation/2.1.x/JavaFormHelpers

此外,我建议阅读 Play 2.3迁移指南中的Bootstrap部分,该部分解释了为什么要删除Bootstrap的内置支持。您应该考虑为最新的Bootstrap版本创建自定义字段助手。如果您考虑迁移到较新版本的Play框架,它将减轻您的痛苦。

http://playframework.com/documentation/2.3.x/Migration23