Подскажите, пожалуйста, как в DataGrid
для определенных строк не показывать контекстное меню. К сожалению у DataGrid.ContextClickEvent
нет метода preventDefault
который бы меня спас(((
Пробовал в addContextClickListener
вызывать setContextMenuEnabled(false)
, но данный вариант действует только для всех последующих вызовов контекстного меню. Также пробовал запрещать вызов контекстного меню в addSelectionListener
, но он тоже очевидно вызывается после вызова меню.
Добрый день.
Чтобы иметь возможность предотвращать открытие контекстного меню для некоторых строк, Вам необходимо расширить компонент DataGrid
и задать для него свою реализацию CubaGridContextMenu
.
Для этого, вам необходимо создать класс наследник WebDataGrid
, который переопределит метод initContextMenu()
, и класс наследник CubaGridContextMenu
, который переопределит onContextClick
в котором можно добавить beforeContextMenuOpenHandler
. Например:
import com.haulmont.cuba.core.entity.Entity;
import com.haulmont.cuba.web.gui.components.WebDataGrid;
import com.haulmont.cuba.web.widgets.grid.CubaGridContextMenu;
import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.ui.Grid;
import java.util.function.Function;
public class WebDataGridExt<E extends Entity> extends WebDataGrid<E> {
private Function<E, Boolean> beforeContextMenuOpenHandler;
@Override
protected void initContextMenu() {
contextMenu = new CubaGridContextMenuExt<>(component);
contextMenu.addGridBodyContextMenuListener(event -> {
if (!component.getSelectedItems().contains(event.getItem())) {
// In the multi select model 'setSelected' adds item to selected set,
// but, in case of context click, we want to have a single selected item,
// if it isn't in a set of already selected items
if (isMultiSelect()) {
component.deselectAll();
}
setSelected(event.getItem());
}
});
}
public void setBeforeContextMenuOpenHandler(Function<E, Boolean> beforeContextMenuOpenHandler) {
this.beforeContextMenuOpenHandler = beforeContextMenuOpenHandler;
}
public class CubaGridContextMenuExt<T> extends CubaGridContextMenu<T> {
public CubaGridContextMenuExt(Grid<T> parentComponent) {
super(parentComponent);
}
@Override
protected void onContextClick(com.vaadin.event.ContextClickEvent event) {
if (!isEnabled()) {
return;
}
// prevent opening context menu in non BODY sections
if (event instanceof Grid.GridContextClickEvent) {
Grid.GridContextClickEvent gridEvent = (Grid.GridContextClickEvent) event;
if (!gridEvent.getSection().equals(GridConstants.Section.BODY)) {
return;
}
fireEvent(new ContextMenuOpenListener.ContextMenuOpenEvent(CubaGridContextMenuExt.this, event));
if (beforeContextMenuOpenHandler != null) {
if (!beforeContextMenuOpenHandler.apply((E) ((Grid.GridContextClickEvent) event).getItem())) {
return;
}
}
open(event.getClientX(), event.getClientY());
}
}
}
}
Чтобы компонент мог использоваться во всем приложении, необходимо зарегистрировать его, создав файл ui-component.xml
в корневом пакете web модуля и зарегистрировав его в web-app.properties
:
ui-component.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<components xmlns="http://schemas.haulmont.com/cuba/components.xsd">
<component>
<name>dataGrid</name>
<class>com.company.sales.web.gui.components.WebDataGridExt</class>
</component>
</components>
web-app.properties
cuba.web.componentsConfig = +com/company/sales/ui-component.xml
После чего, созданный компонент можно использовать в экранах:
@Inject
private DataGrid<Product> dataGrid;
@Subscribe
private void onInit(InitEvent event) {
((WebDataGridExt<Product>) dataGrid).setBeforeContextMenuOpenHandler(item -> false);
}
Полный код можно найти в демо приложении demo.zip (116,0 КБ).