Skip to content

Commit 35339a9

Browse files
committed
fix #1123 Fix TableRow selectable flag not working as expected
1 parent 385c972 commit 35339a9

File tree

7 files changed

+221
-34
lines changed

7 files changed

+221
-34
lines changed

domino-ui/src/main/java/org/dominokit/domino/ui/datatable/DataTable.java

Lines changed: 102 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.dominokit.domino.ui.datatable.events.SelectAllEvent;
4242
import org.dominokit.domino.ui.datatable.events.TableDataUpdatedEvent;
4343
import org.dominokit.domino.ui.datatable.events.TableEvent;
44+
import org.dominokit.domino.ui.datatable.events.TableSelectionDisableEvent;
4445
import org.dominokit.domino.ui.datatable.model.SearchContext;
4546
import org.dominokit.domino.ui.elements.DivElement;
4647
import org.dominokit.domino.ui.elements.TBodyElement;
@@ -631,18 +632,20 @@ public void selectAll() {
631632
* @return the current DataTable instance
632633
*/
633634
public DataTable<T> selectAll(SelectionCondition<T> selectionCondition) {
634-
if (tableConfig.isMultiSelect() && !tableRows.isEmpty()) {
635-
for (TableRow<T> tableRow : tableRows) {
636-
if (selectionCondition.isAllowSelection(this, tableRow)) {
637-
withPauseSelectionListenersToggle(
638-
true,
639-
field -> {
640-
tableRow.select();
641-
});
635+
if (isSelectable()) {
636+
if (tableConfig.isMultiSelect() && !tableRows.isEmpty()) {
637+
for (TableRow<T> tableRow : tableRows) {
638+
if (selectionCondition.isAllowSelection(this, tableRow)) {
639+
withPauseSelectionListenersToggle(
640+
true,
641+
field -> {
642+
tableRow.select();
643+
});
644+
}
642645
}
646+
triggerSelectionListeners(null, getSelection());
647+
fireTableEvent(SelectAllEvent.of(true, selectionCondition));
643648
}
644-
triggerSelectionListeners(null, getSelection());
645-
fireTableEvent(SelectAllEvent.of(true, selectionCondition));
646649
}
647650
return this;
648651
}
@@ -678,6 +681,86 @@ public DataTable<T> deselectAll(SelectionCondition<T> selectionCondition) {
678681
return this;
679682
}
680683

684+
/**
685+
* Selects a collection of table rows.
686+
*
687+
* @param rows the collection of table rows to be selected
688+
* @return the current DataTable instance
689+
*/
690+
public DataTable<T> selectRows(Collection<TableRow<T>> rows) {
691+
if (isSelectable() && nonNull(rows) && !rows.isEmpty()) {
692+
if (tableConfig.isMultiSelect()) {
693+
withPauseSelectionListenersToggle(
694+
true,
695+
field -> {
696+
for (TableRow<T> tableRow : rows) {
697+
tableRow.select();
698+
}
699+
});
700+
triggerSelectionListeners(null, getSelection());
701+
} else {
702+
rows.stream().reduce((first, second) -> second).ifPresent(TableRow::select);
703+
}
704+
}
705+
return this;
706+
}
707+
708+
/**
709+
* Deselects a collection of table rows.
710+
*
711+
* @param rows the collection of table rows to be deselected
712+
* @return the current DataTable instance
713+
*/
714+
public DataTable<T> deselectRows(Collection<TableRow<T>> rows) {
715+
if (nonNull(rows) && !rows.isEmpty()) {
716+
withPauseSelectionListenersToggle(
717+
true,
718+
field -> {
719+
for (TableRow<T> tableRow : rows) {
720+
tableRow.deselect();
721+
}
722+
});
723+
triggerDeselectionListeners(null, getSelection());
724+
}
725+
return this;
726+
}
727+
728+
/**
729+
* Selects a collection of records.
730+
*
731+
* @param records the collection of records to be selected
732+
* @return the current DataTable instance
733+
*/
734+
public DataTable<T> selectRecords(Collection<T> records) {
735+
if (nonNull(records) && !records.isEmpty()) {
736+
Set<T> recordSet = new HashSet<>(records);
737+
List<TableRow<T>> rows =
738+
tableRows.stream()
739+
.filter(row -> recordSet.contains(row.getRecord()))
740+
.collect(Collectors.toList());
741+
selectRows(rows);
742+
}
743+
return this;
744+
}
745+
746+
/**
747+
* Deselects a collection of records.
748+
*
749+
* @param records the collection of records to be deselected
750+
* @return the current DataTable instance
751+
*/
752+
public DataTable<T> deselectRecords(Collection<T> records) {
753+
if (nonNull(records) && !records.isEmpty()) {
754+
Set<T> recordSet = new HashSet<>(records);
755+
List<TableRow<T>> rows =
756+
tableRows.stream()
757+
.filter(row -> recordSet.contains(row.getRecord()))
758+
.collect(Collectors.toList());
759+
deselectRows(rows);
760+
}
761+
return this;
762+
}
763+
681764
/**
682765
* Determines if the table rows are selectable.
683766
*
@@ -688,6 +771,15 @@ public boolean isSelectable() {
688771
return this.selectable;
689772
}
690773

774+
public DataTable<T> setSelectable(boolean selectable) {
775+
this.selectable = selectable;
776+
if (!selectable) {
777+
withPauseSelectionListenersToggle(true, field -> deselectAll());
778+
}
779+
fireTableEvent(new TableSelectionDisableEvent(selectable));
780+
return this;
781+
}
782+
691783
/**
692784
* Pauses the execution of selection listeners.
693785
*

domino-ui/src/main/java/org/dominokit/domino/ui/datatable/TableRow.java

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public class TableRow<T> extends BaseDominoElement<HTMLTableRowElement, TableRow
6161
private boolean selectionListenersPaused = false;
6262
private Set<SelectionListener<? super TableRow<T>, ? super TableRow<T>>> selectionListeners;
6363
private Set<SelectionListener<? super TableRow<T>, ? super TableRow<T>>> deselectionListeners;
64-
private boolean selectable;
64+
private boolean selectable = true;
6565

6666
private FieldsGrouping rowFieldsGroup;
6767
private boolean draggable = true;
@@ -133,20 +133,22 @@ public TableRow<T> select() {
133133
* @return The current instance of TableRow for chaining purposes.
134134
*/
135135
private TableRow<T> doSelect(boolean selectChildren) {
136-
if (!hasFlag(DataTable.DATA_TABLE_ROW_FILTERED)) {
137-
this.selected = true;
138-
if (selectChildren) {
139-
getChildren().forEach(TableRow::select);
136+
if (this.isSelectable() && this.dataTable.isSelectable()) {
137+
if (!hasFlag(DataTable.DATA_TABLE_ROW_FILTERED)) {
138+
this.selected = true;
139+
if (selectChildren) {
140+
getChildren().forEach(TableRow::select);
141+
}
142+
Optional.ofNullable(parent)
143+
.ifPresent(
144+
tableRow -> {
145+
if (tableRow.shouldBeSelected()) {
146+
tableRow.doSelect(false);
147+
}
148+
});
149+
triggerSelectionListeners(this, this);
150+
this.dataTable.triggerSelectionListeners(this, dataTable.getSelection());
140151
}
141-
Optional.ofNullable(parent)
142-
.ifPresent(
143-
tableRow -> {
144-
if (tableRow.shouldBeSelected()) {
145-
tableRow.doSelect(false);
146-
}
147-
});
148-
triggerSelectionListeners(this, this);
149-
this.dataTable.triggerSelectionListeners(this, dataTable.getSelection());
150152
}
151153
return this;
152154
}
@@ -383,7 +385,7 @@ public TableRow<T> select(boolean silent) {
383385
*/
384386
@Override
385387
public TableRow<T> deselect(boolean silent) {
386-
return setSelected(true, silent);
388+
return setSelected(false, silent);
387389
}
388390

389391
/**
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright © 2019 Dominokit
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.dominokit.domino.ui.datatable.events;
18+
19+
/**
20+
* The {@code TableSelectionDisableEvent} class represents an event that occurs when toggling the
21+
* border of a DataTable.
22+
*/
23+
public class TableSelectionDisableEvent implements TableEvent {
24+
25+
/** The event type for the table bordered event. */
26+
public static final String TABLE_SELECTION_DISABLE_EVENT = "table-selection-disable-event";
27+
28+
/** A flag indicating whether the table is bordered or not. */
29+
private final boolean selectable;
30+
31+
/**
32+
* Constructs a new {@code TableSelectionDisableEvent} with the specified bordered flag.
33+
*
34+
* @param selectable {@code true} if the table should have borders, {@code false} otherwise
35+
*/
36+
public TableSelectionDisableEvent(boolean selectable) {
37+
this.selectable = selectable;
38+
}
39+
40+
/**
41+
* Checks if the table is bordered.
42+
*
43+
* @return {@code true} if the table is bordered, {@code false} otherwise
44+
*/
45+
public boolean isSelectable() {
46+
return selectable;
47+
}
48+
49+
/**
50+
* Retrieves the type of this event.
51+
*
52+
* @return the event type
53+
*/
54+
@Override
55+
public String getType() {
56+
return TABLE_SELECTION_DISABLE_EVENT;
57+
}
58+
}

domino-ui/src/main/java/org/dominokit/domino/ui/datatable/plugins/selection/SelectionPlugin.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,13 @@
3434
import org.dominokit.domino.ui.datatable.*;
3535
import org.dominokit.domino.ui.datatable.events.OnBeforeDataChangeEvent;
3636
import org.dominokit.domino.ui.datatable.events.TableDataUpdatedEvent;
37+
import org.dominokit.domino.ui.datatable.events.TableSelectionDisableEvent;
3738
import org.dominokit.domino.ui.datatable.plugins.DataTablePlugin;
3839
import org.dominokit.domino.ui.forms.CheckBox;
3940
import org.dominokit.domino.ui.icons.Icon;
4041
import org.dominokit.domino.ui.icons.lib.Icons;
42+
import org.dominokit.domino.ui.style.BooleanCssClass;
43+
import org.dominokit.domino.ui.style.CssClass;
4144
import org.dominokit.domino.ui.utils.DominoEvent;
4245
import org.dominokit.domino.ui.utils.HasSelectionListeners;
4346
import org.dominokit.domino.ui.utils.Selectable;
@@ -51,6 +54,12 @@
5154
* @see DataTablePlugin
5255
*/
5356
public class SelectionPlugin<T> implements DataTablePlugin<T> {
57+
58+
private static final CssClass dui_table_selection_disabled = () -> "dui-table-selection-disabled";
59+
private static final CssClass dui_table_selection_checkbox = () -> "dui-table-selection-checkbox";
60+
private static final CssClass dui_table_selection_indicator =
61+
() -> "dui-table-selection-indicator";
62+
5463
private Selectable<TableRow<T>> selectedRow;
5564
private Supplier<Element> singleSelectIndicator = () -> Icons.check().element();
5665
private SelectionCondition<T> selectionCondition = (table, row) -> true;
@@ -60,6 +69,7 @@ public class SelectionPlugin<T> implements DataTablePlugin<T> {
6069
private List<T> oldSelection = new ArrayList<>();
6170
private boolean retainSelectionOnDataChange = false;
6271
private CheckBox headerCheckBox;
72+
private boolean enabled = true;
6373

6474
/** Creates a new `SelectionPlugin` with default settings. */
6575
public SelectionPlugin() {}
@@ -133,9 +143,14 @@ public void onHeaderAdded(DataTable<T> dataTable, ColumnConfig<T> column) {
133143
if (column.isUtilityColumn()) {
134144
if (dataTable.getTableConfig().isMultiSelect()) {
135145
column.appendChild(
136-
div().addCss(dui_order_20).appendChild(createMultiSelectHeader(dataTable)));
146+
div()
147+
.addCss(dui_order_20, dui_table_selection_indicator)
148+
.appendChild(createMultiSelectHeader(dataTable)));
137149
} else {
138-
column.appendChild(div().addCss(dui_order_20).appendChild(createSingleSelectHeader()));
150+
column.appendChild(
151+
div()
152+
.addCss(dui_order_20, dui_table_selection_indicator)
153+
.appendChild(createSingleSelectHeader()));
139154
}
140155
}
141156
}
@@ -158,7 +173,7 @@ private Element createSingleSelectHeader() {
158173
*/
159174
private Element createSingleSelectCell(DataTable<T> dataTable, RowCellInfo<T> cell) {
160175
Element clonedIndicator = Js.uncheckedCast(singleSelectIndicator.get());
161-
elementOf(clonedIndicator).addCss(dui_fg_accent);
176+
elementOf(clonedIndicator).addCss(dui_fg_accent, dui_table_selection_indicator);
162177

163178
EventListener clickListener =
164179
evt -> {
@@ -359,7 +374,7 @@ public SelectionPlugin<T> setSingleSelectIcon(Supplier<Icon<?>> singleSelectIcon
359374

360375
private CheckBox createCheckBox(Optional<TableRow<T>> tableRow) {
361376
CheckBox checkBox = checkBoxCreator.get(tableRow);
362-
checkBox.addCss(dui_minified, dui_hide_label);
377+
checkBox.addCss(dui_minified, dui_hide_label, dui_table_selection_checkbox);
363378
return checkBox;
364379
}
365380

@@ -426,6 +441,14 @@ public void handleEvent(DominoEvent event) {
426441
updateHeaderCheckBox(this.datatable.getSelectedItems());
427442
}
428443
}
444+
445+
if (TableSelectionDisableEvent.TABLE_SELECTION_DISABLE_EVENT.equals(event.getType())) {
446+
updateSelectionState(this.datatable.isSelectable());
447+
}
448+
}
449+
450+
private void updateSelectionState(boolean selectable) {
451+
this.datatable.addCss(BooleanCssClass.of(dui_table_selection_disabled, !selectable));
429452
}
430453

431454
/**

domino-ui/src/main/java/org/dominokit/domino/ui/utils/Clipboard.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
@JsType(isNative = true, namespace = JsPackage.GLOBAL)
3434
public class Clipboard {
3535

36+
@JsOverlay
37+
public static Clipboard instance() {
38+
return Js.<DominoNavigator>uncheckedCast(DomGlobal.window.navigator).clipboard;
39+
}
40+
3641
/**
3742
* Reads data from the clipboard.
3843
*
@@ -65,21 +70,21 @@ public class Clipboard {
6570

6671
@JsOverlay
6772
public static Promise<JsArray<ClipboardItem>> get() {
68-
return Js.<DominoNavigator>uncheckedCast(DomGlobal.window.navigator).clipboard.read();
73+
return instance().read();
6974
}
7075

7176
@JsOverlay
7277
public static Promise<String> getText() {
73-
return Js.<DominoNavigator>uncheckedCast(DomGlobal.window.navigator).clipboard.readText();
78+
return instance().readText();
7479
}
7580

7681
@JsOverlay
7782
public static Promise<Any> put(ClipboardItem item) {
78-
return Js.<DominoNavigator>uncheckedCast(DomGlobal.window.navigator).clipboard.write(item);
83+
return instance().write(item);
7984
}
8085

8186
@JsOverlay
8287
public static Promise<Any> put(String text) {
83-
return Js.<DominoNavigator>uncheckedCast(DomGlobal.window.navigator).clipboard.writeText(text);
88+
return instance().writeText(text);
8489
}
8590
}

domino-ui/src/main/java/org/dominokit/domino/ui/utils/DominoEvent.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,7 @@ public interface DominoEvent {
2121
*
2222
* @return the event type
2323
*/
24-
String getType();
24+
default String getType() {
25+
return getClass().getName();
26+
}
2527
}

domino-ui/src/main/resources/org/dominokit/domino/ui/public/css/domino-ui/dui-components/domino-ui-datatable.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,9 @@
292292
--dui-datatable-even-bg-color: var(--dui-datatable-row-highlight-bg-color, var(--dui-accent-l-3));
293293
--dui-datatable-odd-bg-color: var(--dui-datatable-row-highlight-bg-color, var(--dui-accent-l-3));
294294
--dui-bg-clr: var(--dui-datatable-row-highlight-bg-color, var(--dui-accent-l-3));
295+
}
296+
297+
.dui-table-selection-disabled .dui.dui-table-selection-indicator,
298+
.dui-table-selection-disabled .dui.dui-table-selection-checkbox {
299+
display: none;
295300
}

0 commit comments

Comments
 (0)