Ordering new composite entity during inline editing in the table

I have a Master-detail tables screen where after i have created a new row, the new row is displayed at the bottom of the table even it has a specific column populated programmatically. Is there any way I can show it in order? Pls see the screen print.

On the other hand, the composite entity is set to order DESC but when I display in the screen it doesn’t display in DESC order.
Extract from the Entity BankTran


 @OrderBy("bankTran.bankTranLine.entryNumber DESC")
    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "bankTran")
    protected List<BankTranLine> bankTranLine;

I have prepared an example of sorting details of an entity if it is a composition. Please see https://github.com/knstvk/cuba-sample-sort-composition

It is based on the Sales sample, changes are as follows:

  • Added entryNum attribute to OrderLine entity

@Table(name = "SALES_ORDER_LINE")
@Entity(name = "sales$OrderLine")
public class OrderLine extends StandardEntity {

    @Column(name = "ENTRY_NUM")
    protected Integer entryNum;
  • Collection of order lines in Order is now of type List, added @OrderBy annotation:

@Table(name = "SALES_ORDER")
@Entity(name = "sales$Order")
public class Order extends StandardEntity {

    @OrderBy("entryNum")
    @Composition
    @OnDelete(DeletePolicy.CASCADE)
    @OneToMany(mappedBy = "order")
    protected List<OrderLine> lines;
  • In OrderEdit controller, add the following methods to sort records and initialize entry numbers:

public class OrderEdit extends AbstractEditor<Order> {

    @Override
    protected void postInit() {
        // sort and init next number on screen opening
        sortLines();
        initNextEntryNum();

        // sort and init next number after each addition or deletion
        linesTableCreate.setAfterCommitHandler(entity -> {
            sortLines();
            initNextEntryNum();
        });
        linesTableRemove.setAfterRemoveHandler(removedItems -> {
            fixEntryNumbers();
            sortLines();
            initNextEntryNum();
        });
    }


    private void sortLines() {
        linesTable.sortBy(linesDs.getMetaClass().getPropertyPath("entryNum"), true);
    }

    private void initNextEntryNum() {
        Integer lastNum = linesDs.getItems().stream()
                .map(OrderLine::getEntryNum)
                .max(Integer::compareTo)
                .orElse(0);
        linesTableCreate.setInitialValues(ParamsMap.of("entryNum", lastNum + 1));
    }

    private void fixEntryNumbers() {
        int num = 1;
        for (OrderLine orderLine : linesDs.getItems()) {
            orderLine.setEntryNum(num++);
        }
    }
  • You may also want to disable sorting the table by clicking column headers:

    <table id="linesTable"
           sortable="false"
           width="100%">
  • If you want to sort in descending order, change the annotation and the sortLines() method in the controller:

    @OrderBy("entryNum DESC")
    ...
    protected List<OrderLine> lines;

    private void sortLines() {
        linesTable.sortBy(linesDs.getMetaClass().getPropertyPath("entryNum"), false);
    }

Thank you so much Konstantin, that helped.
Basically I was looking for the same related to inline table edit, and it works apparently but need a little more help in a specific situation as described below:

To illustrate, I have added few Entity, screen etc. like PurchaseOrder, PurchaseOrderLine, Product etc in your sample project. You will find the purchase order screen has inline edit functionality. When I create the first or 2nd record it works but it doesn’t work for 3rd or more records as i have some difficulty in catching the last record in DESC order as follows:

The PO screen automatically inserts a new row when the user enters a quantity and if it is the last record.
I can catch the last record using “Iterables.getLast” and move the cursor there accordingly after adding a new item when using ASC sorting but it doesn’t work using “Iterables.getFirst” when I need the first item while sorting is in DESC order , here is my codes:


   }else if ("quantity".equals(e.getProperty())) {
                if(e.getItem().getQuantity().longValue()>0) {
                    if (Iterables.getFirst(purchaseOrderLineDs.getItemIds()).equals(e.getItem().getId())) {
                            addNewRow();
                    }
                }
            }

Thus sorting and moving cursor to the right cell was not possible. Thanks for any help.

  1. If we compare the following two code blocks (one from your sample), which one is supposed to have better performance in case i have a large number of line records and i am doing a lot of CRUDs? I guess your code.

   for (OrderLine details : orderLineDs.getItems()) {
            if(details.getEntryNum()>0) {
                max = Math.max(max, details.getEntryNum());
            }
        }
        max++;
        line.setEntryNum(max);

Integer lastNum = orderLineDs.getItems().stream()
                .map(OrderLine::getEntryNum)
                .max(Integer::compareTo)
                .orElse(0);
        line.setEntryNum(lastNum+1);

I have attached the project and if you want you can put it in GitHub after fixing in case it helps others. my few other asked questions are also illustrated in this project.

cuba-sample-sort-composition-master.zip (662.2K)

Hi Konstantin Krivopustov,
In example: https://github.com/knstvk/cuba-sample-sort-composition.
I want to make MoveUp/MoveDown buttons to move record’s position in “linesTable” . Could you please create in this example or please help me how to do it!

1 Like

Hi Nguyen,

Here it is:


    public void moveUp() {
        OrderLine selectedLine = linesTable.getSingleSelected();
        if (selectedLine == null)
            return;
        int i = getItem().getLines().indexOf(selectedLine);
        if (i == 0)
            return;
        // create a temporary copy of the collection
        ArrayList<OrderLine> lines = new ArrayList<>(getItem().getLines());
        // modify entryNum attributes
        Integer num = selectedLine.getEntryNum();
        selectedLine.setEntryNum(num - 1);
        lines.get(i - 1).setEntryNum(num);
        // sort copy according to the new order
        lines.sort(Comparator.comparingInt(OrderLine::getEntryNum));
        // refill the datasource
        for (OrderLine line : lines) {
            linesDs.excludeItem(line);
        }
        for (OrderLine line : lines) {
            linesDs.includeItem(line);
        }
        // select the same item
        linesTable.setSelected(selectedLine);
    }

    public void moveDown() {
        OrderLine selectedLine = linesTable.getSingleSelected();
        if (selectedLine == null)
            return;
        int i = getItem().getLines().indexOf(selectedLine);
        if (i == getItem().getLines().size() - 1)
            return;
        // create a temporary copy of the collection
        ArrayList<OrderLine> lines = new ArrayList<>(getItem().getLines());
        // modify entryNum attributes
        Integer num = selectedLine.getEntryNum();
        selectedLine.setEntryNum(num + 1);
        lines.get(i + 1).setEntryNum(num);
        // sort copy according to the new order
        lines.sort(Comparator.comparingInt(OrderLine::getEntryNum));
        // refill the datasource
        for (OrderLine line : lines) {
            linesDs.excludeItem(line);
        }
        for (OrderLine line : lines) {
            linesDs.includeItem(line);
        }
        // select the same item
        linesTable.setSelected(selectedLine);
    }

The project is also updated.

Perfect work! Thank you very much!

A post was split to a new topic: Up/Down buttons in table