Attempting to set Composition table's default sort order

Hello,

I’ve got a composition table on an Edit screen that I need to find a way to change the default sort order of the data collection, but I haven’t found the way to do so yet, I don’t believe. Will I have to set a “sorter” for this data collection in a custom class, or is there a less confusing solution?

Thanks!
Adam

Hello Adam,

you can try to set “sort” directly in table’s column:

<column id="name" sort="ASCENDING"/>

or using order by in the query.

See documentation about column’s sort attribute.

@Pinyazhin
I appreciate the info, but I need to join the sort to an additional entiity.

Could you provide more details about your problem? Do you need to sort nested CollectionContainer?

Yes, this composition is a nested data container, which doesn’t seem to provide many visible options to order the query. The columns I need to sort are a custom attribute “completionDate” and the automatically created “created_ts”.

I need to sort by: completion_date asc nulls first, created_ts asc.

Thanks

Unfortunately, DataContainer does not support sorting by two columns. You can use OrderBy annotation on OneToMany relation (it also can be done via Entity Designer):

@OrderBy("completionDate ASC, createTs ASC")

Or sort nested DataContainer in memory:

@Subscribe
public void onAfterShow(AfterShowEvent event) {
    List<TestEntity> items = nestedDc.getMutableItems();
    items.sort((o1, o2) -> {
       // sorting
    });
}

Thank you. But the first method doesn’t seem to be functioning correctly. I’ve got this set as follows:
Screen Shot 2020-06-18 at 4.19.44 PM

And the results are as follows:
Screen Shot 2020-06-18 at 4.19.58 PM

The four entries were created in order (Test1, Test2, Test3, Test4), so it’s obviously sorting by something, but it certainly doesn’t seem to be the way that I am directing it to in the annotation.

OrderBy sorts elements while the collection is loaded. When we create new entity sorting is not invoked. I guess this container should be sorted manually when a new entity is added to the container.

Okay, by this, I’m guessing you’re referring to your “Or sort nested DataContainer in memory” example?

@Subscribe
public void onAfterShow(AfterShowEvent event) {
    List<TestEntity> items = nestedDc.getMutableItems();
    items.sort((o1, o2) -> {
       // sorting
    });
}

If so, I’m not familiar with doing it this way, and can’t seem to find documentation. Would you mind providing an example of what to do in the example where it shows // sorting?

Thanks

List.sort() is not part of the CUBA framework, so you can find a lot of information about sorting in the internet. For your case the sorting will look like this:

protected void sortCollection() {
    List<OrderLine> orderLines = nestedDc.getMutableItems();
    orderLines.sort((o1, o2) -> {
        Date date1 = o1.getCompletionDate();
        Date date2 = o2.getCompletionDate();

        int result = Objects.compare(date1, date2, Comparator.nullsFirst(Comparator.naturalOrder()));
        if (result != 0) {
            return result;
        }

        Date createTs1 = o1.getCreateTs();
        Date createTs2 = o2.getCreateTs();

        return Objects.compare(createTs1, createTs2, Comparator.nullsFirst(Comparator.naturalOrder()));
    });
}

You can subscribe to CollectionChangeEvent and there invoke sorting items:

@Subscribe(id = "nestedDc", target = Target.DATA_CONTAINER)
public void onNestedDcCollectionChange(CollectionContainer.CollectionChangeEvent<Note> event) {
    sortCollection();
}
2 Likes

Thanks Roman! Above and beyond support!