我正在使用Play framework 2.2。我有一个关于表单中的多个复选框的问题以及如何正确绑定加上处理它们。我正在寻找Java解决方案。
假设我们有一个博客网站。我们希望实现当用户创建/编辑博客条目时,他们可以选择向该博客条目添加零到多个标签的功能。这些标记选项显示为表单上的一长串复选框。例如,如果他/她在您的业余时间创建博客条目并在月球上做10件事情"并且希望将其与"明星凝视","行走"和"高尔夫"标签,他/她只需在创建过程中检查相应的复选框。
我不确定如何将模型绑定到视图或如何在提交请求后处理复选框列表。这是一个实验性代码示例。
首先我们有模型:(它们是ebean实体)
public class Blog extends Model {
...
@ManyToMany(cascade=CascadeType.REMOVE)
public List<Tag> tags = new ArrayList<>();
...
}
public class Tag extends Model {
@Id
public Long id;
public String name;
...
}
在视图中,我们将完整的标签列表传递给视图: (我不确定这种方法是否正确)
@(tags: java.util.List[Tag], blogEntryForm: Form[Blog])
...
@form(routes.Application.create(), 'id -> "blogEntryForm") {
...
@for((tag, index) <- tags.zipWithIndex) {
<div class="checkbox">
<label>
<input type="checkbox" name="tags[@index]" value="@tag.id">
@tag.name
</label>
</div>
}
...
}
在控制器中,我们处理表格:
public static Result createBlogEntry() {
Form<Blog> filledForm = Form.form(Blog.class).bindFromRequest();
if (filledForm.hasErrors()) {
...
}
// process checkboxes
???
}
非常感谢任何帮助。
答案 0 :(得分:2)
这似乎有效。
@(tags: java.util.List[Tag], blogEntryForm: Form[Blog])
@helper.form(routes.Application.createBlogEntry(), 'id -> "blogEntryForm") {
@for((tag, index) <- tags.zipWithIndex) {
<div class="checkbox">
<label>
<input type="checkbox" name="tags[@index].id" value="@tag.id">
@tag.name
</label>
</div>
}
<input type="submit" />
}
在我的控制器中我有
public static Result renderTestForm() {
Tag tag1 = new Tag();
tag1.id = 1L;
tag1.name = "tag1";
Tag tag2 = new Tag();
tag2.id = 2L;
tag2.name = "tag2";
List<Tag> tagList = new ArrayList<>();
tagList.add(tag1);
tagList.add(tag2);
Form<Blog> blogForm = Form.form(Blog.class);
return ok(views.html.testForm.render(tagList, blogForm));
}
public static Result createBlogEntry() {
Form<Blog> filledForm = Form.form(Blog.class).bindFromRequest();
if (filledForm.hasErrors()) {
return ok();
}
// process checkboxes
Blog b = filledForm.get();
b.save();
play.Logger.debug(filledForm.toString());
play.Logger.debug(filledForm.get().toString());
List<Blog> bList = Blog.finder.all();
List<Tag> tList = Tag.finder.all();
play.Logger.debug("********");
play.Logger.debug(bList.toString());
play.Logger.debug(tList.toString());
play.Logger.debug("********");
return ok();
}
这只是为了测试整个过程是否正常,因此我为视图中的复选框创建了两个标记并进行渲染。 createBlogEntry
方法只生成调试输出,以确保数据已成功绑定到Blog
objec。
我的路线文件有这些。
GET /testForm controllers.Application.renderTestForm
POST /testForm controllers.Application.createBlogEntry
这是我的模特。
@Entity
@Table(name = "blogs")
public class Blog extends Model {
@Id
public Long id;
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "blog_tags")
public List<Tag> tags = new ArrayList<>();
public String toString() {
String s = "";
for (Tag t : tags) {
s += " " + t.toString();
}
return s;
}
public static final Finder<Long, Blog> finder = new Finder<>(Long.class, Blog.class);
}
@Entity
@Table(name = "tags")
public class Tag {
@Id
public Long id;
public String name;
@ManyToMany(mappedBy = "tags")
public List<Blog> blogs = new ArrayList<>();
public static final Model.Finder<Long, Tag> finder = new Model.Finder<>(Long.class, Tag.class);
}
我的代码中没有注释,因为在测试它是否有用时我没有使用数据库。