如何在Play 2.2.1表单上命名ManyToMany复选框?

时间:2014-02-09 15:19:31

标签: java playframework playframework-2.2

我有以下两个Java类:

Person.java

@Entity
public class Person extends Model {
@Id
public Long id;
@ManyToOne
public Category category = new Category();
@ManyToMany
@JoinTable(joinColumns = {@JoinColumn(name = "person_id")}, inverseJoinColumns = {@JoinColumn(name = "category_id")}, name = "category_person")
public List<Category> categories = new ArrayList<>();


}

Category.java

@Entity
public class Category extends Model {
@Id
public Long id;
public String description;
@OneToMany
public Person person;
@ManyToMany(mappedBy = "categories")
public List<Person> persons = new ArrayList<>();
}

在控制器中我有

public static Result blank() {
    Form<Person> personForm = Form.form(Person.class);
    return ok(blank.render(personForm));
}

如何通过复选框构建表单以反映Person和Category之间的ManyToMany关系?

我试过

@Category.find.order("description asc").findList().map { c =>
                <input type="checkbox" name="categories[@c.id].id" value="@c.id"/> @c.description <br />
        }

但是当我试图保存那个告诉我的人时

[PersistenceException: ManyToMany bean models.Category@11ac3fd does not have an Id value.]

如果我尝试

@Category.find.order("description asc").findList().map { c =>
                <input type="checkbox" name="categories[]" value="@c.id"/> @c.description <br />
        }

验证失败,它告诉我categories[0] has an Invalid Value

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

我找到了问题的解决方案:我需要注册自定义DataBinder。这将告诉Play! (特别是Form对象)如何将输入到表单中的值绑定到特定模型的实例。

首先在Global.java文件夹中创建的app文件中注册自定义DataBinder。我的代码包含:

public class Global extends GlobalSettings {

public void onStart(Application app) {
    Formatters.register(Category.class, new Formatters.SimpleFormatter<Category>() {
        @Override
        public Category parse(String text, Locale locale) throws ParseException {
            return Category.find.byId(Long.parseLong(text));
        }

        @Override
        public String print(Category category, Locale locale) {
            return category.id+"";
        }
    });
}

接下来,在我的表单中,我将ManyToMany Categories复选框命名如下:

<input type="checkbox" name="categories[]" value="@category.id" /> @category.description <br />

然而,并非全部。我必须满足必须使用填充信息重新呈现表单的实例,例如用户编辑他的个人资料这意味着我需要预先检查用户在注册时选择的复选框。这是我使用的代码:

@defining(personForm("categories").indexes.map { i => personForm("categories")("[" + i + "]").value }) { values =>
    @Category.find.all().map { category =>
        <input type="checkbox"
        name="categories[]"
        value="@category.id"
    @if(values.contains(Some(category.id.toString()))) { checked } /> @category.description <br />
    }
}

如果你问我有点复杂,但这是我必须采取的路线,因为我想将Form<>传递给模板而不是POJO。

我希望这有助于某人。