Сортировка при TextField в каждой строке DataGrid

Добрый день,

Интересует решение для следующей проблемы.
Мне надо возможность редактирования данных в одной колонке но каждой строке DataGrid без необходимости перехода в редактор строки. Т.е. TextField поля всех строк всегда доступны для редактирования.

Я могу сделать генерированную колонку где создаю TextField и использую ComponentRenderer. Это работает, но мне необходимо чтобы колонка была доступна для сортировки. При попытке установки setSortable(true) для созданного столбца с TextField получаю ошибку:

java.lang.IllegalStateException: Can't set column Column[propertyId:orderQuantityCalculate] sortable. Container doesn't support sorting by property orderQuantityCalculate
 	at com.vaadin.ui.Grid$Column.setSortable(Grid.java:3795)
 	at com.haulmont.cuba.web.gui.components.WebDataGrid$ColumnImpl.updateSortable(WebDataGrid.java:3013)
 	at com.haulmont.cuba.web.gui.components.WebDataGrid$ColumnImpl.setSortable(WebDataGrid.java:3008)

Если не устанавливать setSortable то просто не сортируется.

И второй вопрос … я могу по кнопке таб двигаться на следующую строку, но выбранная (подсвеченная) строка DataGrid не меняется. Как мне поменять выбранную строку в DataGrid? Есть событие получения фокуса по которому можно было бы установить Selected у DataGrid?

Добрый день.

  1. Вы можете установить атрибут editorBuffered="false", тогда отдельные ячейки станут редактируемыми без перехода в редактор строки. Колонкам, которые не должны редактироваться, следует установить editable="false"
  2. Если Вы имеете ввиду использование Tab при открытом редакторе, то можно повесить слушатель на открытие редактора и программно выделять строку соответствующую редактируемой сущности.
@Inject
private DataGrid<Order> ordersDataGrid;
@Inject
private CollectionDatasource<Order, UUID> ordersDs;

@Override
public void init(Map<String, Object> params) {
    ordersDataGrid.addEditorOpenListener(event -> {
        Order item = ordersDs.getItem((UUID) event.getItemId());
        ordersDataGrid.setSelected(item);
    });
}

Спасибо, Глеб, идея понятна, но editorBuffered=false не совсем работает. Да, при нажатии Enter я перехожу на следующую строку. Но Tab и Shift-Tab не отрабатываются. Есть возможность по Tab менять значение и идти на следующую строку а по Shift-Tab вверх?

С генерируемыми TextField это работает, т…к. это разные компоненты.

Кстати по Shift-Enter данные грузятся из БД и удаляют все изменения незакомиченные. Это так и должно быть?

Спасибо

На самом деле они отрабатывают, но не редатируемые колонки не пропускаются, т.е. нужно нажать несколько раз Tab, чтобы перейти на следующую строку.

Это стандартное сочетание клавиш для применения фильтра.

Точно, спасибо!

Тогда все же несколько вопросов:

  1. Можно ли реализовать сортировку по генерируемому полю типа TextField?
  2. Или сдклать так чтоб Tab и Shift-Tab пропускали нередактируемые ячейки?
  3. Или можно Renderer для поля сделать сразу в TextField вместо генерируемой колонки не трогая datasource? Это сложно?
  4. Как выделить строку как selected при получении фокуса редактором в этой строке?

Желательно малой кровью :slight_smile:

Спасибо

Нет. Дело в том, что генератор колонки вызывается по требованию для видимых строк и все значения не известны, следовательно невозможно сортировать.

Сложно сказать без доп. исследования этого вопроса.

Renderer написать не сложно. Не совсем понял, что значит “не трогая datasource”.

@Inject
private DataGrid<Order> ordersDataGrid;
@Inject
private CollectionDatasource<Order, UUID> ordersDs;

@Override
public void init(Map<String, Object> params) {
    ordersDataGrid.addEditorOpenListener(event -> {
        Order item = ordersDs.getItem((UUID) event.getItemId());
        ordersDataGrid.setSelected(item);
    });
}

Возможно этот Vaadin add-on поможет решить Вашу задачу.

В документации описанно как получить Vaadin компонент.

С уважением,
Глеб

1 симпатия

Добрый день - можете помочь написать custom renderer, который для конкретной ячейки DataGrid создавал бы TextField, на который я мог бы повесить listener и изменять данные в datasource? Что-то типа ComponentRenderer, но где поле в datasource BigDecimal, а клиенту шлется TextField? Не переходя в редактирование DataGrid - просто всегда.
Т.е. я надеюсь что при этом сортировка будет работать, поскольку тип колонки в datasource по прежнему BigDecimal.
Или такой вариант невозможен?

Спасибо

В качестве примера, посмотрите на com.haulmont.cuba.web.gui.components.renderers.WebButtonRenderer. Это должно дать представление о создании рендерера в виде UI компонента и отправки событий на сервер.

Так же я завел тикет на проблему сортировки генерируемых колонок.