Adding better handling for checkbox column based row selection (#21553)

* Adding better handling for checkbox column based row selection

* Replacing any with proper typings
This commit is contained in:
Aasim Khan
2023-01-18 01:20:26 -08:00
committed by GitHub
parent 85eb7b8824
commit 3b31d1018f
2 changed files with 57 additions and 22 deletions

View File

@@ -28,6 +28,11 @@ export interface ICheckboxCellActionEventArgs {
column: number;
}
export interface ICheckAllActionEventArgs {
checked: boolean;
column: number;
}
// Actions expected on checkbox click
export enum ActionOnCheck {
selectRow = 0,
@@ -57,7 +62,9 @@ export class CheckboxSelectColumn<T extends Slick.SlickData> implements Slick.Pl
public index: number;
private _headerCheckbox: HTMLInputElement;
private _onChange = new Emitter<ICheckboxCellActionEventArgs>();
private _onCheckAllChange = new Emitter<ICheckAllActionEventArgs>();
public readonly onChange: vsEvent<ICheckboxCellActionEventArgs> = this._onChange.event;
public readonly onCheckAllChange: vsEvent<ICheckAllActionEventArgs> = this._onCheckAllChange.event;
constructor(options?: ICheckboxSelectColumnOptions, columnIndex?: number) {
this._options = mixin(options, defaultOptions, false);
@@ -129,23 +136,8 @@ export class CheckboxSelectColumn<T extends Slick.SlickData> implements Slick.Pl
this._grid.invalidateRow(row);
this._grid.render();
this._grid.setActiveCell(row, this.index);
this.checkSelectAll();
if (this._options.actionOnCheck === ActionOnCheck.selectRow) {
this.updateSelectedRows();
} else {
this._onChange.fire({ checked: !currentValue.checked, row: row, column: this.index });
}
}
private updateSelectedRows(): void {
const checkedRows = [];
const rows = this._grid.getDataLength();
for (let i = 0; i < rows; i++) {
if (this.getCheckboxPropertyValue(i).checked) {
checkedRows.push(i);
}
}
this._grid.setSelectedRows(checkedRows);
this.updateSelectAllCheckboxState();
this._onChange.fire({ checked: !currentValue.checked, row: row, column: this.index });
}
private handleHeaderClick(e: Event, args?: Slick.OnHeaderClickEventArgs<T>): void {
@@ -174,11 +166,11 @@ export class CheckboxSelectColumn<T extends Slick.SlickData> implements Slick.Pl
for (let i = 0; i < rows; i++) {
this.setCheckboxPropertyValue(i, this._headerCheckbox.checked);
}
this._grid.updateColumnHeader(this._options.columnId!, `<input type="checkbox" tabIndex="0" ${this._headerCheckbox.checked ? 'checked' : ''} title=${HeaderCheckboxTitle}/>`, this._options.toolTip);
if (this._options.actionOnCheck === ActionOnCheck.selectRow) {
this.updateSelectedRows();
}
this._onCheckAllChange.fire({
checked: this._headerCheckbox.checked,
column: this.index
});
this._grid.invalidateAllRows();
this._grid.render();
}
@@ -190,7 +182,7 @@ export class CheckboxSelectColumn<T extends Slick.SlickData> implements Slick.Pl
}
}
private checkSelectAll(): void {
private updateSelectAllCheckboxState(): void {
const rows = this._grid.getDataLength();
let checked = true;
for (let i = 0; i < rows; i++) {

View File

@@ -286,6 +286,9 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
this._register(this._table);
this._register(attachTableStyler(this._table, this.themeService));
this._register(this._table.onSelectedRowsChanged((e, data) => {
if (this.isCheckboxColumnsUsedForSelection()) {
return;
}
this.selectedRows = data.rows;
this.fireEvent({
eventType: ComponentEventType.onSelectedRowChanged,
@@ -445,6 +448,8 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
}, index));
this._register(this._checkboxColumns.get(col.value).onChange((state) => {
this.data[state.row][state.column] = state.checked;
this.setPropertyFromUI<any[][]>((props, value) => props.data = value, this.data);
this.fireEvent({
eventType: ComponentEventType.onCellAction,
args: {
@@ -454,6 +459,34 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
name: name
}
});
if (checkboxAction === ActionOnCheck.selectRow) {
const selectedRows: number[] = [];
this.data.forEach((row, index) => {
if (row[state.column]) {
selectedRows.push(index);
}
});
this.selectedRows = selectedRows;
this.fireEvent({
eventType: ComponentEventType.onSelectedRowChanged,
args: selectedRows
});
}
}));
this._register(this._checkboxColumns.get(col.value).onCheckAllChange((state) => {
this.data.forEach((row, index) => {
row[state.column] = state.checked;
});
this.setPropertyFromUI<any[][]>((props, value) => props.data = value, this.data);
if (checkboxAction === ActionOnCheck.selectRow) {
this.selectedRows = state.checked ? this.data.map((v, i) => i) : [];
this.fireEvent({
eventType: ComponentEventType.onSelectedRowChanged,
args: this.selectedRows
});
}
}));
}
}
@@ -621,6 +654,16 @@ export default class TableComponent extends ComponentBase<azdata.TableComponentP
}
}
/**
* Returns true if the checkbox column is used for row selection in the table
*/
private isCheckboxColumnsUsedForSelection(): boolean {
return this.columns.some(c => {
const checkboxAction = <ActionOnCheck>(c.options ? (<azdata.CheckboxColumnOption>c.options).actionOnCheckbox : c.action);
return checkboxAction === ActionOnCheck.selectRow
});
}
// CSS-bound properties
public get data(): any[][] {