Load Collection Datasource and its children (nested collection datasource) using Next and Previous Button

I have 2 collection datasource.

Authors : Name, List Books, Age, Salary.
Books : Name, ManyToOne Author, Published Date.

Author Details Screen will be on the Left and Book Details Screen on the Right.

When the screen load, 1st author from Author collection is loaded on the left (Author Details Screen). On the right, 1st Book published by that author is display on the Book Details Screen . Using next or previous button, I need to load the different Books belonging to the Author on the left.

I also need to display different author using next and previous button, the changes (1st book of the loaded author) needs to be updated on the right automatically.

I can also create or delete an author or book belonging to the author. When we create an author, the new author should be displayed on screen. I should be able to create Books for the newly created author on the right. On deleting the current author, the author as well as the books belonging to the author needs to be deleted and the 1st author in collection or the previously displayed author needs to be loaded.

Is there any sample implementation or any idea on how to proceed?

Thank you in advance for help.

Hi,

Here’s the simple implementation that illustrates the base idea. The table’s datasource ItemChangeListener is used to update another collectionDatasource.
Next and Previous buttons invoke methods that iterate through this collectionDatasource using prevItemId() and nextItemId() methods of the CollectionDatasource.Ordered interface.
Everything beyond this you can implement yourself. If not, please post a new specific question following the forum guidelines.

split-screen.xml

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        caption="msg://caption"
        class="com.company.demo.web.author.SplitScreen"
        messagesPack="com.company.demo.web.author">
<dsContext>
    <groupDatasource id="authorsDs"
                     class="com.company.demo.entity.Author"
                     view="author-view">
        <query>
            <![CDATA[select e from demo$Author e]]>
        </query>
    </groupDatasource>
    <collectionDatasource id="booksDs"
                     class="com.company.demo.entity.Book"
                     view="book-view">
        <query>
            <![CDATA[select e from demo$Book e where e.author.id = :custom$author]]>
        </query>
    </collectionDatasource>
</dsContext>
    <dialogMode height="600"
                width="800"/>
    <layout>
        <split id="split"
               height="100%"
               orientation="horizontal"
               width="100%">
            <groupBox id="authorBox"
                      caption="msg://author"
                      height="100%"
                      spacing="true">
                <groupTable id="authorsTable"
                            height="100%"
                            width="100%">
                    <columns>
                        <column id="name"/>
                    </columns>
                    <rows datasource="authorsDs"/>
                </groupTable>
            </groupBox>
            <groupBox id="bookBox"
                      caption="msg://book"
                      height="100%"
                      expand="panel"
                      spacing="true">
                <fieldGroup id="bookFieldGroup"
                            datasource="booksDs">
                    <column width="250px">
                        <field property="name"/>
                    </column>
                </fieldGroup>
                <buttonsPanel id="panel">
                    <button id="prevBtn"
                            enable="false"
                            caption="msg://prevBtn"
                            invoke="showPrevBook"/>
                    <button id="nextBtn"
                            enable="false"
                            caption="msg://nextBtn"
                            invoke="showNextBook"/>
                </buttonsPanel>
            </groupBox>
        </split>
    </layout>
</window>

SplitScreen.java

public class SplitScreen extends AbstractWindow {

    @Inject
    private CollectionDatasource.Ordered<Book, UUID> booksDs;
    @Inject
    private Button prevBtn;
    @Inject
    private Button nextBtn;
    @Inject
    private GroupDatasource<Author, UUID> authorsDs;

    @Override
    public void init(Map<String, Object> params) {
        authorsDs.addItemChangeListener(e -> {
            booksDs.refresh(ParamsMap.of("author", e.getItem()));
            booksDs.setItem(booksDs.getItems().iterator().next());
            checkButtonsState(booksDs.getItem().getId());
        });
    }

    public void showNextBook() {
        Book currentBook = booksDs.getItem();
        Book nextBook = booksDs.getItem(booksDs.nextItemId(currentBook.getId()));
        booksDs.setItem(nextBook);
        checkButtonsState(nextBook.getId());
    }

    public void showPrevBook() {
        Book currentBook = booksDs.getItem();
        Book prevBook = booksDs.getItem(booksDs.prevItemId(currentBook.getId()));
        booksDs.setItem(prevBook);
        checkButtonsState(prevBook.getId());
    }

    private void checkButtonsState(UUID bookId) {
        nextBtn.setEnabled(!booksDs.isLastId(bookId) || booksDs.isFirstId(bookId));
        prevBtn.setEnabled(booksDs.isLastId(bookId) || !booksDs.isFirstId(bookId));
    }
}

demo.zip (98.6 KB)

Hi,

Thanks for your help. Your demo was very useful.

Very Sorry for the delay. I have been away for a month.

1 Like