Skip to content

Commit

Permalink
Merge pull request #32 from czeckd/format-layout
Browse files Browse the repository at this point in the history
Format layout
  • Loading branch information
czeckd authored May 10, 2017
2 parents 309f69a + 271579e commit 7215c1e
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 30 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
Angular Dual-Listbox
=========

The **angular-dual-listbox** is an Angular 2+ component that provides two lists controls side-by-side that allows items in one list to be moved to the other list via drag-and-drop and/or a button-based interface. The component supports multiple select options from the list and programatic setting of list sources.
The **angular-dual-listbox** is an Angular 2+ component that provides two lists controls side-by-side that allows items in one list to be moved to the other list via drag-and-drop and/or a button-based interface.
The component supports multiple select options from the list, programatic setting of list sources, and layout with direction and button formatting.

A [working demo](http://czeckd.github.io/angular-dual-listbox/demo/) shows the dual listbox in action.

Expand Down Expand Up @@ -37,6 +38,7 @@ The following parameters can be set on a dual-list:
- **display** - The field of each object for displaying the object each the
lists, default is ``_name``.
- **height** - The height of the lists, default is ``100px``.
- **format** - A format object, default is ``{ add: 'Add', remove: 'Remove', all: 'All', none: 'None', direction: 'left-to-right' }``
- **filter** - A boolean whether or not to display a filter for the lists,
default is ``false``.
- **sort** - A boolean whether or not to keep the lists sorted, default is
Expand Down
74 changes: 58 additions & 16 deletions app/demo-app.component.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { Component, OnInit } from '@angular/core';

import { DualListComponent } from 'angular-dual-listbox';


@Component({
selector: 'demo-app',
template: `
<div class="container-fluid">
<p></p>
<dual-list [sort]="keepSorted" [source]="source" [key]="key" [display]="display" [filter]="filter"
[(destination)]="confirmed" height="265px"></dual-list>
<dual-list [sort]="keepSorted" [source]="source" [key]="key" [display]="display" [filter]="filter"
[(destination)]="confirmed" height="265px" [format]="format"></dual-list>
<ul class="nav nav-tabs" style="margin-top:50px;">
<li [class.active]="tab===1"><a (click)="tab=1">Arrays</a><li>
<li [class.active]="tab===2"><a (click)="tab=2">Programmatic changes</a></li>
<li [class.active]="tab===2"><a (click)="tab=2">Format</a></li>
<li [class.active]="tab===3"><a (click)="tab=3">Programmatic changes</a></li>
</ul>
<div class="tab-content">
Expand All @@ -22,6 +26,36 @@ import { Component, OnInit } from '@angular/core';
</div>
<div class="tab-pane" [class.active]="tab===2">
<form class="form" style="margin:20px 0;">
<label>Direction</label><br/>
<div class="form-group">
<div class="btn-group">
<button type="button" class="btn" [ngClass]="{ 'btn-primary' : sourceLeft, 'btn-default' : !sourceLeft }"
(click)="swapDirection()">left-to-right</button>
<button type="button" class="btn" [ngClass]="{ 'btn-primary' : !sourceLeft, 'btn-default' : sourceLeft }"
(click)="swapDirection()">right-to-left</button>
</div>
</div>
<div class="form-group">
<label>Add button</label>
<input class="form-control col-sm-2" [(ngModel)]="format.add" name="addBtn">
</div>
<div class="form-group">
<label>Remove button</label>
<input class="form-control col-sm-2" [(ngModel)]="format.remove" name="rmBtn">
</div>
<div class="form-group">
<label>All button</label>
<input class="form-control col-sm-2" [(ngModel)]="format.all" name="allBtn">
</div>
<div class="form-group">
<label>None button</label>
<input class="form-control col-sm-2" [(ngModel)]="format.none" name="noneBtn">
</div>
</form>
</div>
<div class="tab-pane" [class.active]="tab===3">
<div class="row" style="margin-top:20px;">
<div class="col-sm-6">
<label>Modify parent's source</label>
Expand All @@ -36,26 +70,26 @@ import { Component, OnInit } from '@angular/core';
<form class="form-inline well">
<button class="btn btn-default" (click)="doAdd()">Add</button>
<button class="btn btn-default" (click)="doRemove()">Remove</button>
</form>
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<label>General</label><br/>
<form class="form-inline well">
<button class="btn btn-default" (click)="doFilter()">{{filterBtn()}}</button>
<button class="btn btn-default" (click)="doSwap()">Swap source</button>
<button class="btn btn-primary" (click)="doReset()">Reset</button>
</form>
<div class="row">
<div class="col-sm-12">
<label>General</label><br/>
<form class="form-inline well">
<button class="btn btn-default" (click)="doFilter()">{{filterBtn()}}</button>
<button class="btn btn-default" (click)="doSwap()">Swap source</button>
<button class="btn btn-primary" (click)="doReset()">Reset</button>
</form>
</div>
</div>
</div>
</div>
</div>
`
})

export class DemoAppComponent implements OnInit{

export class DemoAppComponent implements OnInit {
tab = 1;
keepSorted = true;
key:string;
Expand All @@ -65,6 +99,9 @@ export class DemoAppComponent implements OnInit{
confirmed:Array<any>;
userAdd = '';

sourceLeft = true;
format:any = DualListComponent.DEFAULT_FORMAT;

private sourceStations:Array<any>;
private sourceChessmen:Array<any>;

Expand Down Expand Up @@ -106,7 +143,7 @@ export class DemoAppComponent implements OnInit{
{ key: 30, station: 'Elk Park', state: 'CO' },
{ key: 31, station: 'Silverton', state: 'CO' },
{ key: 32, station: 'Eureka', state: 'CO' }
];
];

private chessmen:Array<any> = [
{ _id: 1, name: 'Pawn' },
Expand Down Expand Up @@ -200,4 +237,9 @@ export class DemoAppComponent implements OnInit{
return (this.filter ? 'Hide Filter' : 'Show Filter');
}

swapDirection() {
this.sourceLeft = !this.sourceLeft;
this.format.direction = this.sourceLeft ? DualListComponent.LTR : DualListComponent.RTL;
}

}
Binary file modified images/dual-listbox.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions lib/dual-list.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ div.record-picker::-webkit-scrollbar-thumb:hover {
}

/* &nbsp;&nbsp;&nbsp;&#9654; */
button[name='addBtn']::after {
.point-right::after {
content: "\00A0\00A0\00A0\25B6";
}

/* &#9664;&nbsp;&nbsp;&nbsp; */
button[name='removeBtn']::before {
.point-left::before {
content: "\25C0\00A0\00A0\00A0";
}

Expand Down
21 changes: 11 additions & 10 deletions lib/dual-list.component.html
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<div class="dual-list">
<div class="listbox">
<div class="listbox" [ngStyle]="{ 'order' : direction() ? 1 : 2, 'margin-left' : direction() ? 0 : '10px' }">
<button type="button" name="addBtn" class="btn btn-primary btn-block"
(click)="moveItem(available, confirmed)"
[disabled]="available.pick.length === 0">Add</button>
(click)="moveItem(available, confirmed)" [ngClass]="direction() ? 'point-right' : 'point-left'"
[disabled]="available.pick.length === 0">{{format.add}}</button>

<form *ngIf="filter" class="filter">
<input class="form-control" name="filterSource" [(ngModel)]="available.picker" (ngModelChange)="onFilter(available)">
Expand All @@ -21,16 +21,17 @@

<div class="button-bar">
<button type="button" class="btn btn-primary pull-left" (click)="selectAll(available)"
[disabled]="isAllSelected(available)">All</button>
[disabled]="isAllSelected(available)">{{format.all}}</button>
<button type="button" class="btn btn-default pull-right" (click)="selectNone(available)"
[disabled]="!isAnySelected(available)">None</button>
[disabled]="!isAnySelected(available)">{{format.none}}</button>
</div>
</div>

<div class="listbox" style="margin-left:10px;">
<!-- style="margin-left:10px;" -->
<div class="listbox" [ngStyle]="{ 'order' : direction() ? 2 : 1, 'margin-left' : direction() ? '10px' : 0 }">
<button type="button" name="removeBtn" class="btn btn-primary btn-block"
(click)="moveItem(confirmed, available)"
[disabled]="confirmed.pick.length === 0">Remove</button>
(click)="moveItem(confirmed, available)" [ngClass]="direction() ? 'point-left' : 'point-right'"
[disabled]="confirmed.pick.length === 0">{{format.remove}}</button>

<form *ngIf="filter" class="filter">
<input class="form-control" name="filterDestination" [(ngModel)]="confirmed.picker" (ngModelChange)="onFilter(confirmed)">
Expand All @@ -49,9 +50,9 @@

<div class="button-bar">
<button type="button" class="btn btn-primary pull-left" (click)="selectAll(confirmed)"
[disabled]="isAllSelected(confirmed)">All</button>
[disabled]="isAllSelected(confirmed)">{{format.all}}</button>
<button type="button" class="btn btn-default pull-right" (click)="selectNone(confirmed)"
[disabled]="!isAnySelected(confirmed)">None</button>
[disabled]="!isAnySelected(confirmed)">{{format.none}}</button>
</div>
</div>
</div>
34 changes: 34 additions & 0 deletions lib/dual-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ export class DualListComponent implements DoCheck, OnChanges {
static AVAILABLE_LIST_NAME = 'available';
static CONFIRMED_LIST_NAME = 'confirmed';

static LTR = 'left-to-right';
static RTL = 'right-to-left';

static DEFAULT_FORMAT = { add: 'Add', remove: 'Remove', all: 'All', none: 'None', direction: DualListComponent.LTR };

@Input() key:string = typeof this.key !== 'undefined' ? this.key : '_id';
@Input() display:string = typeof this.display !== 'undefined' ? this.display : '_name';
@Input() height:string = typeof this.height !== 'undefined' ? this.height : '100px';
@Input() filter:boolean = typeof this.filter !== 'undefined' ? this.filter : false;
@Input() format:any = typeof this.format !== 'undefined' ? this.format : DualListComponent.DEFAULT_FORMAT;
@Input() sort:boolean = typeof this.sort !== 'undefined' ? this.sort : false;
@Input() compare:compareFunction = typeof this.compare !== 'undefined' ? this.compare : undefined;
@Input() source:Array<any>;
Expand Down Expand Up @@ -54,6 +60,30 @@ export class DualListComponent implements DoCheck, OnChanges {
}
}

if (changeRecord['format']) {
this.format = changeRecord['format'].currentValue;

if (typeof(this.format.direction) === 'undefined') {
this.format.direction = DualListComponent.LTR;
}

if (typeof(this.format.add) === 'undefined') {
this.format.add = DualListComponent.DEFAULT_FORMAT.add;
}

if (typeof(this.format.remove) === 'undefined') {
this.format.remove = DualListComponent.DEFAULT_FORMAT.remove;
}

if (typeof(this.format.all) === 'undefined') {
this.format.all = DualListComponent.DEFAULT_FORMAT.all;
}

if (typeof(this.format.none) === 'undefined') {
this.format.none = DualListComponent.DEFAULT_FORMAT.none;
}
}

if (changeRecord['source']) {
this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
this.updatedSource();
Expand Down Expand Up @@ -151,6 +181,10 @@ export class DualListComponent implements DoCheck, OnChanges {
}
}

direction() {
return this.format.direction === DualListComponent.LTR;
}

dragEnd(list:BasicList = null) {
if (list) {
list.dragStart = false;
Expand Down
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "angular-dual-listbox",
"description": "Angular 2+ component for a dual listbox control.",
"version": "4.1.0",
"version": "4.2.0",
"repository": {
"type": "git",
"url": "https://github.com/czeckd/angular-dual-listbox.git"
Expand All @@ -23,6 +23,10 @@
"main": "angular-dual-listbox.bundle.js",
"module": "angular-dual-listbox.module.js",
"types": "index.d.ts",
"keywords": [
"angular",
"listbox"
],
"peerDependencies": {
"@angular/core": ">=4.0.0",
"@angular/forms": ">=4.0.0"
Expand Down

0 comments on commit 7215c1e

Please sign in to comment.