From 6a4f30cb510cc10b20408d9520114748383e1bfa Mon Sep 17 00:00:00 2001 From: Austin Date: Sun, 25 Dec 2016 14:52:54 -0500 Subject: [PATCH] (feature): multi click selection --- demo/app.component.ts | 4 +- demo/module.ts | 4 +- demo/selection/selection-multi-click.ts | 81 ++++++++++++++++++++++ demo/selection/selection-multi.ts | 6 +- docs/changelog.md | 9 +++ src/components/body/selection.component.ts | 17 +++-- src/components/datatable.component.ts | 16 ++++- src/themes/material.scss | 3 +- src/types/selection.type.ts | 1 + src/utils/selection.ts | 10 ++- 10 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 demo/selection/selection-multi-click.ts diff --git a/demo/app.component.ts b/demo/app.component.ts index 5ad03937c..f154091a6 100644 --- a/demo/app.component.ts +++ b/demo/app.component.ts @@ -56,7 +56,8 @@ import { Component } from '@angular/core'; @@ -111,6 +112,7 @@ import { Component } from '@angular/core'; + diff --git a/demo/module.ts b/demo/module.ts index ef99d0ae4..78e5e5bee 100644 --- a/demo/module.ts +++ b/demo/module.ts @@ -41,6 +41,7 @@ import { MultiSelectionComponent } from './selection/selection-multi'; import { SingleSelectionComponent } from './selection/selection-single'; import { MultiDisableSelectionComponent } from './selection/selection-disabled'; import { CheckboxSelectionComponent } from './selection/selection-chkbox'; +import { MultiClickSelectionComponent } from './selection/selection-multi-click'; // -- Columns import { ColumnToggleComponent } from './columns/column-toggle'; @@ -81,7 +82,8 @@ import { ColumnPinningComponent } from './columns/pinning'; MultiDisableSelectionComponent, RxDemoComponent, ContextMenuDemoComponent, - CheckboxSelectionComponent + CheckboxSelectionComponent, + MultiClickSelectionComponent ], imports: [BrowserModule, NgxDatatableModule], bootstrap: [AppComponent] diff --git a/demo/selection/selection-multi-click.ts b/demo/selection/selection-multi-click.ts new file mode 100644 index 000000000..5e4682fbf --- /dev/null +++ b/demo/selection/selection-multi-click.ts @@ -0,0 +1,81 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'multi-click-selection-demo', + template: ` +
+

Multi Click Selection

+
+
+

This demonstrates multi selection table, where any click event causes a selection.

+
+ + + +
+ +
+

Selections

+
    +
  • + {{sel.name}} +
  • +
  • No Selections
  • +
+
+
+ ` +}) +export class MultiClickSelectionComponent { + + rows = []; + + selected = []; + + columns: any[] = [ + { prop: 'name'} , + { name: 'Company' }, + { name: 'Gender' } + ]; + + constructor() { + this.fetch((data) => { + this.rows = data; + }); + } + + fetch(cb) { + const req = new XMLHttpRequest(); + req.open('GET', `assets/data/company.json`); + + req.onload = () => { + cb(JSON.parse(req.response)); + }; + + req.send(); + } + + onSelect({ selected }) { + console.log('Select Event', selected, this.selected); + + this.selected.splice(0, this.selected.length); + this.selected.push(...selected); + } + + onActivate(event) { + console.log('Activate Event', event); + } + +} diff --git a/demo/selection/selection-multi.ts b/demo/selection/selection-multi.ts index 008bc8322..460692cea 100644 --- a/demo/selection/selection-multi.ts +++ b/demo/selection/selection-multi.ts @@ -4,8 +4,12 @@ import { Component } from '@angular/core'; selector: 'multi-selection-demo', template: `
-

Multi Select via Click

+

Multi Select

+
+

This demonstrates multi selection table, use CTRL or SHIFT click to select multiple items.

+
+ ` to `` diff --git a/src/components/body/selection.component.ts b/src/components/body/selection.component.ts index 2af6cb5d5..1a993cf4f 100644 --- a/src/components/body/selection.component.ts +++ b/src/components/body/selection.component.ts @@ -36,28 +36,27 @@ export class DataTableSelectionComponent { const chkbox = this.selectionType === SelectionType.checkbox; const multi = this.selectionType === SelectionType.multi; + const multiClick = this.selectionType == SelectionType.multiClick; let selected: any[] = []; - if (multi || chkbox) { + if (multi || chkbox || multiClick) { if (event.shiftKey) { - const newSelected = [...this.selected]; selected = selectRowsBetween( - newSelected, + [...this.selected], this.rows, index, this.prevIndex, this.getRowSelectedIdx.bind(this)); - } else if (!event.shiftKey) { - selected.push(row); + } else if (event.ctrlKey || multiClick || chkbox) { + selected = selectRows([...this.selected], row, this.getRowSelectedIdx.bind(this)); } else { - const newSelected = [...this.selected]; - selected = selectRows(newSelected, row, this.getRowSelectedIdx.bind(this)); + selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); } } else { - selected.push(row); + selected = selectRows([], row, this.getRowSelectedIdx.bind(this)); } - if(this.selectCheck) { + if(typeof this.selectCheck === 'function') { selected = selected.filter(this.selectCheck.bind(this)); } diff --git a/src/components/datatable.component.ts b/src/components/datatable.component.ts index a424a4a79..2c2948791 100644 --- a/src/components/datatable.component.ts +++ b/src/components/datatable.component.ts @@ -27,6 +27,7 @@ import { scrollbarWidth, setColumnDefaults, throttleable, translateTemplates } f [offsetX]="offsetX" [columns]="columns" [headerHeight]="headerHeight" + [reorderable]="reorderable" [sortAscendingIcon]="cssClasses.sortAscending" [sortDescendingIcon]="cssClasses.sortDescending" [allRowsSelected]="allRowsSelected" @@ -284,7 +285,8 @@ export class DatatableComponent implements OnInit, AfterViewInit, DoCheck { * * - `single` * - `multi` - * - `chkbox`. + * - `chkbox` + * - `multiClick` * * For no selection pass a `falsey`. * Default value: `undefined` @@ -576,6 +578,18 @@ export class DatatableComponent implements OnInit, AfterViewInit, DoCheck { return this.selectionType === SelectionType.multi; } + /** + * CSS class added to root element if mulit click select + * + * @readonly + * @type {boolean} + * @memberOf DatatableComponent + */ + @HostBinding('class.multi-click-selection') + get isMultiClickSelection(): boolean { + return this.selectionType === SelectionType.multiClick; + } + /** * Column templates gathered from `ContentChildren` * if described in your markup. diff --git a/src/themes/material.scss b/src/themes/material.scss index 827ca4c42..ed12347c3 100644 --- a/src/themes/material.scss +++ b/src/themes/material.scss @@ -11,7 +11,8 @@ } &.single-selection, - &.multi-selection { + &.multi-selection, + &.multi-click-selection { .datatable-body-row { &.active, &.active .datatable-row-group { diff --git a/src/types/selection.type.ts b/src/types/selection.type.ts index 3da1a67cb..6311a251c 100644 --- a/src/types/selection.type.ts +++ b/src/types/selection.type.ts @@ -1,6 +1,7 @@ export enum SelectionType { single = 'single' as any, multi = 'multi' as any, + multiClick = 'multiClick' as any, cell = 'cell' as any, checkbox = 'checkbox' as any } diff --git a/src/utils/selection.ts b/src/utils/selection.ts index ec09d0441..cf5bae016 100644 --- a/src/utils/selection.ts +++ b/src/utils/selection.ts @@ -10,7 +10,13 @@ export function selectRows(selected: any[], row: any, comparefn: Function) { return selected; } -export function selectRowsBetween(selected: any[], rows: any[], index: number, prevIndex: number, comparefn: Function) { +export function selectRowsBetween( + selected: any[], + rows: any[], + index: number, + prevIndex: number, + comparefn: Function): any[] { + const reverse = index < prevIndex; for(let i = 0, len = rows.length; i < len; i++) { @@ -43,7 +49,7 @@ export function selectRowsBetween(selected: any[], rows: any[], index: number, p // if in the positive range to be added to `selected`, and // not already in the selected array, add it - if( i >= range.start && i < range.end) { + if(i >= range.start && i < range.end) { if (idx === -1) { selected.push(row); }