Как связать и обработать список флажков в форме, используя игровую среду 2

1

Я использую платформу Play 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
  ???
} 

Любая помощь приветствуется.

Теги:
playframework
forms
checkbox
playframework-2.0

1 ответ

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 успешно.

У моих файлов маршрутов есть эти.

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);

}

У меня не было аннотаций в моем коде, потому что я не использовал базу данных, пока я тестировал, будет ли это работать.

  • 0
    Действительно, и это точно такой же код представления, как у меня выше. Вопрос был в том, как извлечь значения в контроллере, используя какой-то цикл.
  • 0
    Это не тоже самое. bindFromRequest работает непосредственно с этим кодом для привязки к модели блога. Разница заключается в tags[@index].id вместо tags[@index] и @tag.id вместо tag.id Я дополню свой ответ остальной частью моего кода, но я думаю, вы обнаружите, что он в основном совпадает с вашим, за исключением данных фиктивного тестирования.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню