Skip to content

Commit 7215c1e

Browse files
authored
Merge pull request #32 from czeckd/format-layout
Format layout
2 parents 309f69a + 271579e commit 7215c1e

File tree

7 files changed

+113
-30
lines changed

7 files changed

+113
-30
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
Angular Dual-Listbox
44
=========
55

6-
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.
6+
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.
7+
The component supports multiple select options from the list, programatic setting of list sources, and layout with direction and button formatting.
78

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

@@ -37,6 +38,7 @@ The following parameters can be set on a dual-list:
3738
- **display** - The field of each object for displaying the object each the
3839
lists, default is ``_name``.
3940
- **height** - The height of the lists, default is ``100px``.
41+
- **format** - A format object, default is ``{ add: 'Add', remove: 'Remove', all: 'All', none: 'None', direction: 'left-to-right' }``
4042
- **filter** - A boolean whether or not to display a filter for the lists,
4143
default is ``false``.
4244
- **sort** - A boolean whether or not to keep the lists sorted, default is

app/demo-app.component.ts

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import { Component, OnInit } from '@angular/core';
22

3+
import { DualListComponent } from 'angular-dual-listbox';
4+
5+
36
@Component({
47
selector: 'demo-app',
58
template: `
69
<div class="container-fluid">
710
<p></p>
8-
<dual-list [sort]="keepSorted" [source]="source" [key]="key" [display]="display" [filter]="filter"
9-
[(destination)]="confirmed" height="265px"></dual-list>
11+
<dual-list [sort]="keepSorted" [source]="source" [key]="key" [display]="display" [filter]="filter"
12+
[(destination)]="confirmed" height="265px" [format]="format"></dual-list>
1013
1114
<ul class="nav nav-tabs" style="margin-top:50px;">
1215
<li [class.active]="tab===1"><a (click)="tab=1">Arrays</a><li>
13-
<li [class.active]="tab===2"><a (click)="tab=2">Programmatic changes</a></li>
16+
<li [class.active]="tab===2"><a (click)="tab=2">Format</a></li>
17+
<li [class.active]="tab===3"><a (click)="tab=3">Programmatic changes</a></li>
1418
</ul>
1519
1620
<div class="tab-content">
@@ -22,6 +26,36 @@ import { Component, OnInit } from '@angular/core';
2226
</div>
2327
2428
<div class="tab-pane" [class.active]="tab===2">
29+
<form class="form" style="margin:20px 0;">
30+
<label>Direction</label><br/>
31+
<div class="form-group">
32+
<div class="btn-group">
33+
<button type="button" class="btn" [ngClass]="{ 'btn-primary' : sourceLeft, 'btn-default' : !sourceLeft }"
34+
(click)="swapDirection()">left-to-right</button>
35+
<button type="button" class="btn" [ngClass]="{ 'btn-primary' : !sourceLeft, 'btn-default' : sourceLeft }"
36+
(click)="swapDirection()">right-to-left</button>
37+
</div>
38+
</div>
39+
<div class="form-group">
40+
<label>Add button</label>
41+
<input class="form-control col-sm-2" [(ngModel)]="format.add" name="addBtn">
42+
</div>
43+
<div class="form-group">
44+
<label>Remove button</label>
45+
<input class="form-control col-sm-2" [(ngModel)]="format.remove" name="rmBtn">
46+
</div>
47+
<div class="form-group">
48+
<label>All button</label>
49+
<input class="form-control col-sm-2" [(ngModel)]="format.all" name="allBtn">
50+
</div>
51+
<div class="form-group">
52+
<label>None button</label>
53+
<input class="form-control col-sm-2" [(ngModel)]="format.none" name="noneBtn">
54+
</div>
55+
</form>
56+
</div>
57+
58+
<div class="tab-pane" [class.active]="tab===3">
2559
<div class="row" style="margin-top:20px;">
2660
<div class="col-sm-6">
2761
<label>Modify parent's source</label>
@@ -36,26 +70,26 @@ import { Component, OnInit } from '@angular/core';
3670
<form class="form-inline well">
3771
<button class="btn btn-default" (click)="doAdd()">Add</button>
3872
<button class="btn btn-default" (click)="doRemove()">Remove</button>
39-
</form>
73+
</form>
74+
</div>
4075
</div>
41-
</div>
42-
<div class="row">
43-
<div class="col-sm-12">
44-
<label>General</label><br/>
45-
<form class="form-inline well">
46-
<button class="btn btn-default" (click)="doFilter()">{{filterBtn()}}</button>
47-
<button class="btn btn-default" (click)="doSwap()">Swap source</button>
48-
<button class="btn btn-primary" (click)="doReset()">Reset</button>
49-
</form>
76+
<div class="row">
77+
<div class="col-sm-12">
78+
<label>General</label><br/>
79+
<form class="form-inline well">
80+
<button class="btn btn-default" (click)="doFilter()">{{filterBtn()}}</button>
81+
<button class="btn btn-default" (click)="doSwap()">Swap source</button>
82+
<button class="btn btn-primary" (click)="doReset()">Reset</button>
83+
</form>
84+
</div>
5085
</div>
5186
</div>
5287
</div>
5388
</div>
5489
`
5590
})
5691

57-
export class DemoAppComponent implements OnInit{
58-
92+
export class DemoAppComponent implements OnInit {
5993
tab = 1;
6094
keepSorted = true;
6195
key:string;
@@ -65,6 +99,9 @@ export class DemoAppComponent implements OnInit{
6599
confirmed:Array<any>;
66100
userAdd = '';
67101

102+
sourceLeft = true;
103+
format:any = DualListComponent.DEFAULT_FORMAT;
104+
68105
private sourceStations:Array<any>;
69106
private sourceChessmen:Array<any>;
70107

@@ -106,7 +143,7 @@ export class DemoAppComponent implements OnInit{
106143
{ key: 30, station: 'Elk Park', state: 'CO' },
107144
{ key: 31, station: 'Silverton', state: 'CO' },
108145
{ key: 32, station: 'Eureka', state: 'CO' }
109-
];
146+
];
110147

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

240+
swapDirection() {
241+
this.sourceLeft = !this.sourceLeft;
242+
this.format.direction = this.sourceLeft ? DualListComponent.LTR : DualListComponent.RTL;
243+
}
244+
203245
}

images/dual-listbox.png

-55 Bytes
Loading

lib/dual-list.component.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ div.record-picker::-webkit-scrollbar-thumb:hover {
126126
}
127127

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

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

lib/dual-list.component.html

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<div class="dual-list">
2-
<div class="listbox">
2+
<div class="listbox" [ngStyle]="{ 'order' : direction() ? 1 : 2, 'margin-left' : direction() ? 0 : '10px' }">
33
<button type="button" name="addBtn" class="btn btn-primary btn-block"
4-
(click)="moveItem(available, confirmed)"
5-
[disabled]="available.pick.length === 0">Add</button>
4+
(click)="moveItem(available, confirmed)" [ngClass]="direction() ? 'point-right' : 'point-left'"
5+
[disabled]="available.pick.length === 0">{{format.add}}</button>
66

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

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

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

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

5051
<div class="button-bar">
5152
<button type="button" class="btn btn-primary pull-left" (click)="selectAll(confirmed)"
52-
[disabled]="isAllSelected(confirmed)">All</button>
53+
[disabled]="isAllSelected(confirmed)">{{format.all}}</button>
5354
<button type="button" class="btn btn-default pull-right" (click)="selectNone(confirmed)"
54-
[disabled]="!isAnySelected(confirmed)">None</button>
55+
[disabled]="!isAnySelected(confirmed)">{{format.none}}</button>
5556
</div>
5657
</div>
5758
</div>

lib/dual-list.component.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ export class DualListComponent implements DoCheck, OnChanges {
1515
static AVAILABLE_LIST_NAME = 'available';
1616
static CONFIRMED_LIST_NAME = 'confirmed';
1717

18+
static LTR = 'left-to-right';
19+
static RTL = 'right-to-left';
20+
21+
static DEFAULT_FORMAT = { add: 'Add', remove: 'Remove', all: 'All', none: 'None', direction: DualListComponent.LTR };
22+
1823
@Input() key:string = typeof this.key !== 'undefined' ? this.key : '_id';
1924
@Input() display:string = typeof this.display !== 'undefined' ? this.display : '_name';
2025
@Input() height:string = typeof this.height !== 'undefined' ? this.height : '100px';
2126
@Input() filter:boolean = typeof this.filter !== 'undefined' ? this.filter : false;
27+
@Input() format:any = typeof this.format !== 'undefined' ? this.format : DualListComponent.DEFAULT_FORMAT;
2228
@Input() sort:boolean = typeof this.sort !== 'undefined' ? this.sort : false;
2329
@Input() compare:compareFunction = typeof this.compare !== 'undefined' ? this.compare : undefined;
2430
@Input() source:Array<any>;
@@ -54,6 +60,30 @@ export class DualListComponent implements DoCheck, OnChanges {
5460
}
5561
}
5662

63+
if (changeRecord['format']) {
64+
this.format = changeRecord['format'].currentValue;
65+
66+
if (typeof(this.format.direction) === 'undefined') {
67+
this.format.direction = DualListComponent.LTR;
68+
}
69+
70+
if (typeof(this.format.add) === 'undefined') {
71+
this.format.add = DualListComponent.DEFAULT_FORMAT.add;
72+
}
73+
74+
if (typeof(this.format.remove) === 'undefined') {
75+
this.format.remove = DualListComponent.DEFAULT_FORMAT.remove;
76+
}
77+
78+
if (typeof(this.format.all) === 'undefined') {
79+
this.format.all = DualListComponent.DEFAULT_FORMAT.all;
80+
}
81+
82+
if (typeof(this.format.none) === 'undefined') {
83+
this.format.none = DualListComponent.DEFAULT_FORMAT.none;
84+
}
85+
}
86+
5787
if (changeRecord['source']) {
5888
this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
5989
this.updatedSource();
@@ -151,6 +181,10 @@ export class DualListComponent implements DoCheck, OnChanges {
151181
}
152182
}
153183

184+
direction() {
185+
return this.format.direction === DualListComponent.LTR;
186+
}
187+
154188
dragEnd(list:BasicList = null) {
155189
if (list) {
156190
list.dragStart = false;

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "angular-dual-listbox",
33
"description": "Angular 2+ component for a dual listbox control.",
4-
"version": "4.1.0",
4+
"version": "4.2.0",
55
"repository": {
66
"type": "git",
77
"url": "https://github.com/czeckd/angular-dual-listbox.git"
@@ -23,6 +23,10 @@
2323
"main": "angular-dual-listbox.bundle.js",
2424
"module": "angular-dual-listbox.module.js",
2525
"types": "index.d.ts",
26+
"keywords": [
27+
"angular",
28+
"listbox"
29+
],
2630
"peerDependencies": {
2731
"@angular/core": ">=4.0.0",
2832
"@angular/forms": ">=4.0.0"

0 commit comments

Comments
 (0)