Skip to content

Commit

Permalink
(feature): multi click selection
Browse files Browse the repository at this point in the history
  • Loading branch information
amcdnl committed Dec 25, 2016
1 parent bc3df4c commit 6a4f30c
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 16 deletions.
4 changes: 3 additions & 1 deletion demo/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ import { Component } from '@angular/core';
<ul>
<li><a href="#" (click)="state='cell-selection'">Cell</a></li>
<li><a href="#" (click)="state='single-selection'">Single Row</a></li>
<li><a href="#" (click)="state='multi-selection'">Mulit Row</a></li>
<li><a href="#" (click)="state='multi-selection'">Multi Row</a></li>
<li><a href="#" (click)="state='multi-click-selection'">Multi Click Row</a></li>
<li><a href="#" (click)="state='multidisable-selection'">Disable Callback</a></li>
<li><a href="#" (click)="state='chkbox-selection'">Checkbox</a></li>
</ul>
Expand Down Expand Up @@ -111,6 +112,7 @@ import { Component } from '@angular/core';
<multi-selection-demo *ngIf="state === 'multi-selection'"></multi-selection-demo>
<multidisable-selection-demo *ngIf="state === 'multidisable-selection'"></multidisable-selection-demo>
<chkbox-selection-demo *ngIf="state === 'chkbox-selection'"></chkbox-selection-demo>
<multi-click-selection-demo *ngIf="state === 'multi-click-selection'"></multi-click-selection-demo>
<!-- Templates -->
<template-ref-demo *ngIf="state === 'templateref'"></template-ref-demo>
Expand Down
4 changes: 3 additions & 1 deletion demo/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -81,7 +82,8 @@ import { ColumnPinningComponent } from './columns/pinning';
MultiDisableSelectionComponent,
RxDemoComponent,
ContextMenuDemoComponent,
CheckboxSelectionComponent
CheckboxSelectionComponent,
MultiClickSelectionComponent
],
imports: [BrowserModule, NgxDatatableModule],
bootstrap: [AppComponent]
Expand Down
81 changes: 81 additions & 0 deletions demo/selection/selection-multi-click.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Component } from '@angular/core';

@Component({
selector: 'multi-click-selection-demo',
template: `
<div>
<h3>Multi Click Selection</h3>
<div style='float:left;width:75%'>
<div class="info">
<p>This demonstrates multi selection table, where any click event causes a selection.</p>
</div>
<ngx-datatable
class="material"
[rows]="rows"
[columnMode]="'force'"
[columns]="columns"
[headerHeight]="50"
[footerHeight]="50"
[rowHeight]="'auto'"
[limit]="5"
[selected]="selected"
[selectionType]="'multiClick'"
(activate)="onActivate($event)"
(select)='onSelect($event)'>
</ngx-datatable>
</div>
<div class='selected-column'>
<h4>Selections</h4>
<ul>
<li *ngFor='let sel of selected'>
{{sel.name}}
</li>
<li *ngIf="!selected.length">No Selections</li>
</ul>
</div>
</div>
`
})
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);
}

}
6 changes: 5 additions & 1 deletion demo/selection/selection-multi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { Component } from '@angular/core';
selector: 'multi-selection-demo',
template: `
<div>
<h3>Multi Select via Click</h3>
<h3>Multi Select</h3>
<div style='float:left;width:75%'>
<div class="info">
<p>This demonstrates multi selection table, use CTRL or SHIFT click to select multiple items.</p>
</div>
<ngx-datatable
class="material"
[rows]="rows"
Expand Down
9 changes: 9 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 4.1.0
- Feature: Adding multi-click selection
- Bug: Use tracking fn vs inline (#388)
- Bug: Fix AoT header issue (#389)
- Bug: Fix `reorderable` not being honored (#387)
- Bug: Fix multi-select CTRL not working (#381)
- Chore: Upgrade Angular to ^2.4.1
- Docs: Multi-select

## 4.0.0
- BREAKING!!!! - Renamed project from `angular2-datatable` to `ngx-datatable`
and updated components from `<swui-datatable>` to `<ngx-datatable>`
Expand Down
17 changes: 8 additions & 9 deletions src/components/body/selection.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}

Expand Down
16 changes: 15 additions & 1 deletion src/components/datatable.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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`
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion src/themes/material.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
}

&.single-selection,
&.multi-selection {
&.multi-selection,
&.multi-click-selection {
.datatable-body-row {
&.active,
&.active .datatable-row-group {
Expand Down
1 change: 1 addition & 0 deletions src/types/selection.type.ts
Original file line number Diff line number Diff line change
@@ -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
}
10 changes: 8 additions & 2 deletions src/utils/selection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 6a4f30c

Please sign in to comment.