Create model with containing CellList using GWT Editor Framework?

104 Views Asked by At

I have the following model:

class Book {
  String title;
  // getter and setter
}

class Author {
  private name;
  private List<Book> books;
  // getter and setter  
}

I want to create a GWT Widget where I can create an author and create as many books as possible while creating the author in the same view. Here is how it might look like:

enter image description here

You can add as many books as you want:

enter image description here

I want to use the GWT Editor framework to populate the data between the view and the models. Here is how I do it only for the Author model without the list.

My UiBinder:

<g:TextBox ui:field="nameInput"/>

My Widget.java:

public class MyWidgetView {

  @Path(value="name")
  @UiField
  TextBox nameInput;

public interface EditorDriver extends SimpleBeanEditorDriver<Author, MyWidgetView> { }

  @Override
  public SimpleBeanEditorDriver<Author, ?> createEditorDriver() {
    EditorDriver driver = GWT.create(EditorDriver.class);
    driver.initialize(this);
    return driver;
  }

}

In my presenter I created:

SimpleBeanEditorDriver<TriggerDto, ?> editorDriver = getView().createEditorDriver();

This works fine for a simple model but I want to use it for the above author model which contains a List<Book>.

How do I have to setup the UiBinder such that I can add Books to the author and what do I have to do with the editor to get the created list of Books flushed into the author model?

1

There are 1 best solutions below

5
On

Here how you can achieve that. You'll need to create an Editor, a ListEditor and an EditorSource

public class BooksEditor implements IsWidget, IsEditor<ListEditor<Book, BookEditor>> {
    private final HTMLPanel main;
    private final ListEditor<Book, BookEditor>> editor;

    @Inject
    BooksEditor(
            Provider<BookEditor> bookEditorProvider) {
        main = new HTMLPanel("");
        editor = ListEditor.of(new BookEditorSource(bookEditorProvider, main));
    }

    @Override
    public ListEditor<Book, BookEditor> asEditor() {
        return editor;
    }

    @Override
    public Widget asWidget() {
        return main;
    }`
}

public class BookEditorSource extends EditorSource<BookEditor> {
    private final Provider<BookEditor> bookEditorProvider;
    private final HTMLPanel books;

    public BookEditorSource(
            Provider<BookEditor> bookEditorProvider,
            HTMLPanel books) {
        this.bookEditorProvider = bookEditorProvider;
        this.books = books;
    }

    @Override
    public BookEditor create(int index) {
        BookEditor bookEditor = bookEditorProvider.get();
        books.add(bookEditor);

        return bookEditor;
    }

    @Override
    public void dispose(BookEditor subEditor) {
        super.dispose(subEditor);

        books.remove(subEditor);
    }
}

To create the BookEditor class, simply create a new Widget that implements Editor<Book> and create the according UiFields to be able to edit your Book object. The values will be handled by the parent Author SimpleBeanDriver. Then in your MyWidgetView, simply add a UiField :

@UiField(provided = true)
@Path("books")
BooksEditor booksInput;

If you want to add/remove widgets on the fly and synchronize it with the ListEditor, simply work with the BooksEditor class. editor.getList().add(new Book()) will automatically add a new BookEditor in your panel. Calling editor.getList().remove(bookToRemove) will remove it (see the dispose() method in BookEditorSource, it's called when calling remove on the list).