<!DOCTYPE html>
<html>
<head>
<title>angular2 playground</title>
<link rel="stylesheet" type="text/css" href="https://unpkg.com/angular2-data-table/release/datatable.css" />
<link rel="stylesheet" type="text/css" href="https://unpkg.com/angular2-data-table/release/material.css" />
<link href="https://file.myfontastic.com/Jnf54BZCm7mSjGCxNRbfp3/icons.css" rel="stylesheet">
<link rel="stylesheet" href="style.css" />
<script src="https://unpkg.com/zone.js@0.6.23/dist/zone.js"></script>
<script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
<script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
<script src="https://unpkg.com/typescript@1.8.10/lib/typescript.js"></script>
<script src="config.js"></script>
<script>
System.import('app')
.catch(console.error.bind(console));
</script>
</head>
<body>
<my-app>
loading...
</my-app>
</body>
</html>
body{
font-family: 'RobotoDraft', 'Roboto', 'Helvetica Neue, Helvetica, Arial', sans-serif;
text-align: center;
font-style: normal;
font-weight: 300;
font-size: 1.4rem;
line-height: 2rem;
letter-spacing: 0.01rem;
color: #212121;
background-color: #f5f5f5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
margin:20px
}
.datatable {
text-align: left;
width:75%;
margin:0 auto;
}
.datatable.vertical-scroll {
height:70vh;
}
# angular2-data-table basic example
System.config({
//use typescript for compilation
transpiler: 'typescript',
//typescript compiler options
typescriptOptions: {
emitDecoratorMetadata: true
},
//map tells the System loader where to look for things
map: {
app: "./src",
'@angular': 'https://unpkg.com/@angular',
'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.12',
'@swimlane/ngx-datatable': 'https://unpkg.com/@swimlane/ngx-datatable'
},
//packages defines our app package
packages: {
app: {
main: './bootstrap.ts',
defaultExtension: 'ts'
},
'@angular/core': {
main: 'bundles/core.umd.js',
defaultExtension: 'js'
},
'@angular/compiler': {
main: 'bundles/compiler.umd.js',
defaultExtension: 'js'
},
'@angular/common': {
main: 'bundles/common.umd.js',
defaultExtension: 'js'
},
'@angular/platform-browser-dynamic': {
main: 'bundles/platform-browser-dynamic.umd.js',
defaultExtension: 'js'
},
'@angular/platform-browser': {
main: 'bundles/platform-browser.umd.js',
defaultExtension: 'js'
},
'@angular/forms': {
main: 'index.js',
defaultExtension: 'js'
},
'@angular/router': {
main: 'index.js',
defaultExtension: 'js'
},
rxjs: {
defaultExtension: 'js'
}
}
});
//main entry point
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule} from './app';
platformBrowserDynamic().bootstrapModule(AppModule)
//our root app component
import {Component, NgModule, ViewEncapsulation} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { MultiselectDropdownModule } from './ng2-multiselect';
import {
TableOptions,
TableColumn,
ColumnMode
} from '@swimlane/ngx-datatable';
@Component({
selector: 'my-app',
styleUrls: [
'material.css',
'dark.css'
],
encapsulation: ViewEncapsulation.None,
template: `
<ng2-multiselect class="manualFilter"
[options]="dropdowns[col]"
[loading]="isLoading"
[(ngModel)]="multiModels[col]"
[texts]="{'defaultTitle':col}"
(dropdownOpen)="dropdownOpen()"
(dropdownClosed)="dropdownClosed(col)"
>
</ng2-multiselect>
<div>
<h3>basic</h3>
<ngx-datatable
class='material striped'
[rows]='rows'
[limit]='limit'
[columns]='[{name:"Name"},{name:"Gender"},{name:"Company"}]'
[columnMode]='"force"'
[headerHeight]='50'
[footerHeight]='50'
[rowHeight]='"auto"'>
</ngx-datatable>
</div>
<button (click)="toggle()">Limit: {{limit}}</button>
`
})
export class App {
rows = [];
limit = 10;
dropdowns: any = {};
constructor() {
this.fetch((data) => {
this.rows.push(...data);
});
}
fetch(cb) {
const req = new XMLHttpRequest();
req.open('GET', 'https://unpkg.com/@swimlane/ngx-datatable@6.3.0/assets/data/company.json');
req.onload = () => {
cb(JSON.parse(req.response));
};
req.send();
}
toggle() {
this.limit = this.limit === 10 ? 5 : 10;
}
}
@NgModule({
imports: [ BrowserModule, NgxDatatableModule,MultiselectDropdownModule ],
declarations: [ App ],
bootstrap: [ App ]
})
export class AppModule {}
input[type="checkbox"],
input[type="radio"] {
display: none; }
.ngx-datatable.material {
background: #FFF;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
/**
* Shared Styles
*/
/**
* Global Row Styles
*/
/**
* Header Styles
*/
/**
* Body Styles
*/
/**
* Footer Styles
*/ }
.ngx-datatable.material.striped .datatable-row-odd {
background: #eee; }
.ngx-datatable.material.single-selection .datatable-body-row.active,
.ngx-datatable.material.single-selection .datatable-body-row.active .datatable-row-group, .ngx-datatable.material.multi-selection .datatable-body-row.active,
.ngx-datatable.material.multi-selection .datatable-body-row.active .datatable-row-group, .ngx-datatable.material.multi-click-selection .datatable-body-row.active,
.ngx-datatable.material.multi-click-selection .datatable-body-row.active .datatable-row-group {
background-color: #304FFE;
color: #FFF; }
.ngx-datatable.material.single-selection .datatable-body-row.active:hover,
.ngx-datatable.material.single-selection .datatable-body-row.active:hover .datatable-row-group, .ngx-datatable.material.multi-selection .datatable-body-row.active:hover,
.ngx-datatable.material.multi-selection .datatable-body-row.active:hover .datatable-row-group, .ngx-datatable.material.multi-click-selection .datatable-body-row.active:hover,
.ngx-datatable.material.multi-click-selection .datatable-body-row.active:hover .datatable-row-group {
background-color: #193AE4;
color: #FFF; }
.ngx-datatable.material.single-selection .datatable-body-row.active:focus,
.ngx-datatable.material.single-selection .datatable-body-row.active:focus .datatable-row-group, .ngx-datatable.material.multi-selection .datatable-body-row.active:focus,
.ngx-datatable.material.multi-selection .datatable-body-row.active:focus .datatable-row-group, .ngx-datatable.material.multi-click-selection .datatable-body-row.active:focus,
.ngx-datatable.material.multi-click-selection .datatable-body-row.active:focus .datatable-row-group {
background-color: #2041EF;
color: #FFF; }
.ngx-datatable.material:not(.cell-selection) .datatable-body-row:hover,
.ngx-datatable.material:not(.cell-selection) .datatable-body-row:hover .datatable-row-group {
background-color: #eee;
transition-property: background;
transition-duration: .3s;
transition-timing-function: linear; }
.ngx-datatable.material:not(.cell-selection) .datatable-body-row:focus,
.ngx-datatable.material:not(.cell-selection) .datatable-body-row:focus .datatable-row-group {
background-color: #ddd; }
.ngx-datatable.material.cell-selection .datatable-body-cell:hover,
.ngx-datatable.material.cell-selection .datatable-body-cell:hover .datatable-row-group {
background-color: #eee;
transition-property: background;
transition-duration: .3s;
transition-timing-function: linear; }
.ngx-datatable.material.cell-selection .datatable-body-cell:focus,
.ngx-datatable.material.cell-selection .datatable-body-cell:focus .datatable-row-group {
background-color: #ddd; }
.ngx-datatable.material.cell-selection .datatable-body-cell.active,
.ngx-datatable.material.cell-selection .datatable-body-cell.active .datatable-row-group {
background-color: #304FFE;
color: #FFF; }
.ngx-datatable.material.cell-selection .datatable-body-cell.active:hover,
.ngx-datatable.material.cell-selection .datatable-body-cell.active:hover .datatable-row-group {
background-color: #193AE4;
color: #FFF; }
.ngx-datatable.material.cell-selection .datatable-body-cell.active:focus,
.ngx-datatable.material.cell-selection .datatable-body-cell.active:focus .datatable-row-group {
background-color: #2041EF;
color: #FFF; }
.ngx-datatable.material .empty-row {
height: 50px;
text-align: left;
padding: .5rem 1.2rem;
vertical-align: top;
border-top: 0; }
.ngx-datatable.material .loading-row {
text-align: left;
padding: .5rem 1.2rem;
vertical-align: top;
border-top: 0; }
.ngx-datatable.material .datatable-header .datatable-row-left,
.ngx-datatable.material .datatable-body .datatable-row-left {
background-color: #FFF;
background-position: 100% 0;
background-repeat: repeat-y;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAYAAAD5PA/NAAAAFklEQVQIHWPSkNeSBmJhTQVtbiDNCgASagIIuJX8OgAAAABJRU5ErkJggg==); }
.ngx-datatable.material .datatable-header .datatable-row-right,
.ngx-datatable.material .datatable-body .datatable-row-right {
background-position: 0 0;
background-color: #fff;
background-repeat: repeat-y;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABCAYAAAD5PA/NAAAAFklEQVQI12PQkNdi1VTQ5gbSwkAsDQARLAIGtOSFUAAAAABJRU5ErkJggg==); }
.ngx-datatable.material .datatable-header {
border-bottom: 1px solid rgba(0, 0, 0, 0.12); }
.ngx-datatable.material .datatable-header .datatable-header-cell {
text-align: left;
padding: .9rem 1.2rem;
font-weight: 400;
color: rgba(0, 0, 0, 0.54);
vertical-align: bottom;
font-size: 12px;
font-weight: 500; }
.ngx-datatable.material .datatable-header .datatable-header-cell .datatable-header-cell-wrapper {
position: relative; }
.ngx-datatable.material .datatable-header .datatable-header-cell.longpress .draggable::after {
transition: transform 400ms ease, opacity 400ms ease;
opacity: .5;
transform: scale(1); }
.ngx-datatable.material .datatable-header .datatable-header-cell .draggable::after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
margin: -30px 0 0 -30px;
height: 60px;
width: 60px;
background: #eee;
border-radius: 100%;
opacity: 1;
filter: none;
transform: scale(0);
z-index: 9999;
pointer-events: none; }
.ngx-datatable.material .datatable-header .datatable-header-cell.dragging .resize-handle {
border-right: none; }
.ngx-datatable.material .datatable-header .resize-handle {
border-right: solid 1px #eee; }
.ngx-datatable.material .datatable-body .datatable-row-detail {
background: #f5f5f5;
padding: 10px; }
.ngx-datatable.material .datatable-body .datatable-group-header {
background: #f5f5f5;
border-bottom: solid 1px #D9D8D9;
border-top: solid 1px #D9D8D9; }
.ngx-datatable.material .datatable-body .datatable-body-row .datatable-body-cell {
text-align: left;
padding: .9rem 1.2rem;
vertical-align: top;
border-top: 0;
color: rgba(0, 0, 0, 0.87);
transition: width 0.3s ease;
font-size: 14px;
font-weight: 400; }
.ngx-datatable.material .datatable-body .datatable-body-row .datatable-body-group-cell {
text-align: left;
padding: .9rem 1.2rem;
vertical-align: top;
border-top: 0;
color: rgba(0, 0, 0, 0.87);
transition: width 0.3s ease;
font-size: 14px;
font-weight: 400; }
.ngx-datatable.material .datatable-body .progress-linear {
display: block;
position: relative;
width: 100%;
height: 5px;
padding: 0;
margin: 0;
position: absolute; }
.ngx-datatable.material .datatable-body .progress-linear .container {
display: block;
position: relative;
overflow: hidden;
width: 100%;
height: 5px;
-webkit-transform: translate(0, 0) scale(1, 1);
transform: translate(0, 0) scale(1, 1);
background-color: #aad1f9; }
.ngx-datatable.material .datatable-body .progress-linear .container .bar {
transition: all .2s linear;
-webkit-animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1);
animation: query 0.8s infinite cubic-bezier(0.39, 0.575, 0.565, 1);
transition: -webkit-transform .2s linear;
transition: transform .2s linear;
background-color: #106cc8;
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 100%;
height: 5px; }
.ngx-datatable.material .datatable-footer {
border-top: 1px solid rgba(0, 0, 0, 0.12);
font-size: 12px;
font-weight: 400;
color: rgba(0, 0, 0, 0.54); }
.ngx-datatable.material .datatable-footer .page-count {
line-height: 50px;
height: 50px;
padding: 0 1.2rem; }
.ngx-datatable.material .datatable-footer .datatable-pager {
margin: 0 10px; }
.ngx-datatable.material .datatable-footer .datatable-pager li {
vertical-align: middle; }
.ngx-datatable.material .datatable-footer .datatable-pager li.disabled a {
color: rgba(0, 0, 0, 0.26) !important;
background-color: transparent !important; }
.ngx-datatable.material .datatable-footer .datatable-pager li.active a {
background-color: rgba(158, 158, 158, 0.2);
font-weight: bold; }
.ngx-datatable.material .datatable-footer .datatable-pager a {
height: 22px;
min-width: 24px;
line-height: 22px;
padding: 0 6px;
border-radius: 3px;
margin: 6px 3px;
text-align: center;
vertical-align: top;
color: rgba(0, 0, 0, 0.54);
text-decoration: none;
vertical-align: bottom; }
.ngx-datatable.material .datatable-footer .datatable-pager a:hover {
color: rgba(0, 0, 0, 0.75);
background-color: rgba(158, 158, 158, 0.2); }
.ngx-datatable.material .datatable-footer .datatable-pager .datatable-icon-left,
.ngx-datatable.material .datatable-footer .datatable-pager .datatable-icon-skip,
.ngx-datatable.material .datatable-footer .datatable-pager .datatable-icon-right,
.ngx-datatable.material .datatable-footer .datatable-pager .datatable-icon-prev {
font-size: 20px;
line-height: 20px;
padding: 0 3px; }
/**
* Checkboxes
**/
.datatable-checkbox {
position: relative;
margin: 0;
cursor: pointer;
vertical-align: middle;
display: inline-block;
box-sizing: border-box;
padding: 10px 0; }
.datatable-checkbox input[type='checkbox'] {
position: relative;
margin: 0 1rem 0 0;
cursor: pointer;
outline: none; }
.datatable-checkbox input[type='checkbox']:before {
-webkit-transition: all 0.3s ease-in-out;
-moz-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
content: "";
position: absolute;
left: 0;
z-index: 1;
width: 1rem;
height: 1rem;
border: 2px solid #f2f2f2; }
.datatable-checkbox input[type='checkbox']:checked:before {
-webkit-transform: rotate(-45deg);
-moz-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
height: .5rem;
border-color: #009688;
border-top-style: none;
border-right-style: none; }
.datatable-checkbox input[type='checkbox']:after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 1rem;
height: 1rem;
background: #fff;
cursor: pointer; }
/**
* Progress bar animations
*/
@keyframes query {
0% {
opacity: 1;
transform: translateX(35%) scale(0.3, 1); }
100% {
opacity: 0;
transform: translateX(-50%) scale(0, 1); } }
.ngx-datatable.dark {
box-shadow: none;
background: #1b1e27;
border: 1px solid #2f3646;
color: #fff;
font-size: 13px; }
.ngx-datatable.dark .datatable-header {
background: #181b24;
color: #72809b; }
.ngx-datatable.dark .datatable-header .datatable-header-cell {
text-align: left;
padding: .5rem 1.2rem;
font-weight: bold; }
.ngx-datatable.dark .datatable-header .datatable-header-cell .datatable-header-cell-label {
line-height: 24px; }
.ngx-datatable.dark .datatable-body {
background: #1a1e28; }
.ngx-datatable.dark .datatable-body .datatable-body-row {
border-top: 1px solid #2f3646; }
.ngx-datatable.dark .datatable-body .datatable-body-row .datatable-body-cell {
text-align: left;
padding: .5rem 1.2rem;
vertical-align: top; }
.ngx-datatable.dark .datatable-body .datatable-body-row:hover {
background: #171b24;
transition-property: background;
transition-duration: .3s;
transition-timing-function: linear; }
.ngx-datatable.dark .datatable-body .datatable-body-row:focus {
background-color: #232837; }
.ngx-datatable.dark .datatable-body .datatable-body-row.active {
background-color: #1483ff;
color: #FFF; }
.ngx-datatable.dark .datatable-footer {
background: #232837;
color: #72809b;
margin-top: -1px; }
.ngx-datatable.dark .datatable-footer .page-count {
line-height: 50px;
height: 50px;
padding: 0 1.2rem; }
.ngx-datatable.dark .datatable-footer .datatable-pager {
margin: 0 10px;
vertical-align: top; }
.ngx-datatable.dark .datatable-footer .datatable-pager ul li {
margin: 10px 0px; }
.ngx-datatable.dark .datatable-footer .datatable-pager ul li:not(.disabled).active a,
.ngx-datatable.dark .datatable-footer .datatable-pager ul li:not(.disabled):hover a {
background-color: #455066;
font-weight: bold; }
.ngx-datatable.dark .datatable-footer .datatable-pager a {
height: 22px;
min-width: 24px;
line-height: 22px;
padding: 0;
border-radius: 3px;
margin: 0 3px;
text-align: center;
vertical-align: top;
text-decoration: none;
vertical-align: bottom;
color: #72809b; }
.ngx-datatable.dark .datatable-footer .datatable-pager .datatable-icon-left,
.ngx-datatable.dark .datatable-footer .datatable-pager .datatable-icon-skip,
.ngx-datatable.dark .datatable-footer .datatable-pager .datatable-icon-right,
.ngx-datatable.dark .datatable-footer .datatable-pager .datatable-icon-prev {
font-size: 18px;
line-height: 27px;
padding: 0 3px; }
<div class="dropdown">
<button type="button" class="dropdown-toggle" [ngClass]="settings.buttonClasses"
(click)="toggleDropdown()" [disabled]="disabled">
<div class="chips">
<span class="first-chip" [class.on]="numSelected>0">{{texts.defaultTitle}} </span>
<span *ngIf="numSelected>1" class="c-plus">+</span>
<i *ngIf="numSelected>1" class="chip-count">{{numSelected-1}}</i>
</div>
<div *ngIf="loading" class="progress">
<div class="indeterminate"></div>
</div>
</button>
<ul *ngIf="isVisible" class="dropdown-menu" [class.pull-right]="settings.pullRight" [class.dropdown-menu-right]="settings.pullRight" style="height:400px;"
[style.max-height]="settings.maxHeight" style="display: block; height: auto; overflow-y: auto;">
<li class="dropdown-item search" *ngIf="settings.enableSearch">
<div class="input-group input-group-sm">
<span class="input-group-addon" id="sizing-addon3"><i class="fa fa-search"></i></span>
<input type="text" class="form-control" placeholder="{{ texts.searchPlaceholder }}"
aria-describedby="sizing-addon3" [(ngModel)]="searchFilterText" [ngModelOptions]="{standalone: true}">
<span class="input-group-btn" *ngIf="searchFilterText.length > 0">
<button class="btn btn-default btn-secondary" type="button" (click)="clearSearch($event)"><i class="fa fa-times"></i></button>
</span>
</div>
</li>
<li class="dropdown-divider divider" *ngIf="settings.enableSearch"></li>
<li class="dropdown-item" *ngIf="options.length>0">
<a role="menuitem" tabindex="-1" (click)="toggleCheckAll()">
<input type="checkbox" [class.circle]="fewChecked" [checked]="isCheckedAll"/>
<span [ngClass]="settings.itemClasses">{{isCheckedAll ? texts.uncheckAll : texts.checkAll}}</span>
</a>
</li>
<li *ngIf="options.length>0 && (settings.showCheckAll || settings.showUncheckAll)" class="dropdown-divider divider"></li>
<li class="dropdown-item" *ngIf="options.length===0">
<a role="menuitem" tabindex="-1">
<span class="no-records">No records found</span>
</a>
</li>
<li class="dropdown-item" [ngStyle]="getItemStyle(option)" *ngFor="let option of options | searchFilter:searchFilterText"
(click)="!option.isLabel && setSelected(option)" [class.dropdown-header]="option.isLabel">
<ng-template [ngIf]="option.isLabel">
{{ option.value }}
</ng-template>
<a *ngIf="!option.isLabel" role="menuitem" tabindex="-1">
<input type="checkbox" [checked]="isSelected(option)"/>
<span [ngClass]="settings.itemClasses">
{{ option.value }}
</span>
</a>
</li>
</ul>
</div>
a
outline: none !important
.dropdown
min-width: 100px
.dropdown-menu
border-radius: 0
box-shadow: 0px 1px 10px rgba(0, 0, 0, 0.3)
min-width: 200px
.dropdown-toggle
border-radius: 0
background-color: #fff
border: 1px solid #ccc
display: block
width: auto
position: relative
height: 30px
line-height: 30px
padding: 0 0 10px
text-align: initial
width: 100%
.dropdown-menu>li>a
padding: 3px 10px
.input-group
margin: 0 5px
.form-control
border-radius: 0
.input-group-addon:first-child
border-radius: 0
.input-group-btn:last-child>.btn
border-radius: 0
.no-records
text-align: center
display: block
.chips
display: block
width: 100%
position: relative
&:before
content: ''
position: absolute
right: 10px
top: 13px
height: 0px
width: 0px
border-left: 4px solid transparent
border-right: 4px solid transparent
border-top: 4px solid #545454
.first-chip
text-overflow: ellipsis
white-space: nowrap
overflow: hidden
max-width: 120px
display: block
padding-left: 8px
line-height: 30px
height: 30px
font-size: 15px
color: #999
&.on
color: #444
.c-plus
height: 30px
display: inline-block
line-height: 30px
position: absolute
font-weight: 600
top: 0
right: 33px
.chip-count
width: 20px
height: 20px
border-radius: 50%
background-color: #000
color: #fff
display: inline-block
font-style: normal
line-height: 20px
text-align: center
position: absolute
right: 7px
top: 4px
input[type="checkbox"]
-webkit-appearance: none
background: #fff
border: 1px solid #c6c6c6
border-image: -ms-linear-gradient(top, #fff, #fff)
-webkit-border-radius: 1px
border-radius: 1px
height: 13px
left: 1px
margin: 2px 8px 0 0
outline: 0
position: relative
top: 1px
width: 13px
vertical-align: top
input[type="checkbox"]:hover
border: 1px solid #b2b2b2
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .1)
input[type="checkbox"]:active
background-color: #ebebeb
border: 1px solid #c6c6c6
input[type="checkbox"]:focus
border: 1px solid #4d90fe
input[type="checkbox"]:checked:after
background: url(https://ssl.gstatic.com/ui/v1/menu/checkmark_2x.png) no-repeat 0 0 / 21px
content: ''
display: block
height: 21px
left: -5px
position: relative
top: -6px
width: 21px
input[type="checkbox"].circle:after
background-color: #999
content: ''
display: block
height: 7px
left: 2px
position: relative
top: 2px
width: 7px
border-radius: 50%
input[type="checkbox"]:disabled
background-color: #fff
border: 1px solid #e1e1e1
box-shadow: none
opacity: .5
/* Progress Bar
.progress
position: relative
height: 4px
display: block
width: 100%
background-color: #acece6
background-clip: padding-box
overflow: hidden
top: -6px
margin-bottom: 0px
.determinate
position: absolute
background-color: inherit
top: 0
bottom: 0
background-color: #26a69a
transition: width .3s linear
.indeterminate
background-color: #26a69a
&:before
content: ''
position: absolute
background-color: inherit
top: 0
left: 0
bottom: 0
will-change: left, right
animation: indeterminate 2.1s cubic-bezier(0.65, 0.815, 0.735, 0.395) infinite
&:after
content: ''
position: absolute
background-color: inherit
top: 0
left: 0
bottom: 0
will-change: left, right
animation: indeterminate-short 2.1s cubic-bezier(0.165, 0.84, 0.44, 1) infinite
animation-delay: 1.15s
@-webkit-keyframes indeterminate
0%
left: -35%
right: 100%
60%
left: 100%
right: -90%
100%
left: 100%
right: -90%
@keyframes indeterminate
0%
left: -35%
right: 100%
60%
left: 100%
right: -90%
100%
left: 100%
right: -90%
@-webkit-keyframes indeterminate-short
0%
left: -200%
right: 100%
60%
left: 107%
right: -8%
100%
left: 107%
right: -8%
@keyframes indeterminate-short
0%
left: -200%
right: 100%
60%
left: 107%
right: -8%
100%
left: 107%
right: -8%
import {
NgModule,
Component,
Pipe,
OnInit,
DoCheck,
HostListener,
Input,
ElementRef,
Output,
EventEmitter,
forwardRef,
IterableDiffers,
PipeTransform,
ViewEncapsulation,
ChangeDetectionStrategy,
ChangeDetectorRef,
NgZone,
Inject
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, NG_VALUE_ACCESSOR, ControlValueAccessor, Validator, AbstractControl } from '@angular/forms';
const MULTISELECT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiselectDropdown),
multi: true
};
export interface IMultiSelectOption {
key: string;
value: string;
isChecked: boolean;
isLabel?: boolean;
parentId?: any;
params?: any;
}
export interface IMultiSelectSettings {
pullRight?: boolean;
enableSearch?: boolean;
checkedStyle?: 'checkboxes' | 'glyphicon' | 'fontawesome';
buttonClasses?: string;
itemClasses?: string;
selectionLimit?: number;
closeOnSelect?: boolean;
autoUnselect?: boolean;
showCheckAll?: boolean;
showUncheckAll?: boolean;
dynamicTitleMaxItems?: number;
maxHeight?: string;
displayAllSelectedText?: boolean;
}
export interface IMultiSelectTexts {
checkAll?: string;
uncheckAll?: string;
checked?: string;
checkedPlural?: string;
searchPlaceholder?: string;
defaultTitle?: string;
allSelected?: string;
}
@Pipe({
name: 'searchFilter'
})
export class MultiSelectSearchFilter implements PipeTransform {
multiselectDropdown: any;
constructor( @Inject(forwardRef(() => MultiselectDropdown)) multiselectDropdown: MultiselectDropdown) {
this.multiselectDropdown = multiselectDropdown;
}
transform(options: Array<IMultiSelectOption> = [], args: string): Array<IMultiSelectOption> {
const matchPredicate = (option: IMultiSelectOption) => option.value.toLowerCase().indexOf((args || '').toLowerCase()) > -1;
let temp = options.filter((option: IMultiSelectOption) => {
return matchPredicate(option);
});
this.multiselectDropdown.dataSetUpdated(temp);
return temp
}
}
@Component({
selector: 'ng2-multiselect',
providers: [MULTISELECT_VALUE_ACCESSOR],
templateUrl: './ng2-multiselect.html',
styleUrls: ['./ng2-multiselect.sass'],
encapsulation: ViewEncapsulation.None
})
export class MultiselectDropdown implements OnInit, DoCheck, ControlValueAccessor, Validator {
@Input() options: Array<IMultiSelectOption> = [];
@Input() settings: IMultiSelectSettings;
@Input() texts: IMultiSelectTexts;
@Input() disabled: boolean = false;
@Input() loading:boolean = false;
@Output() selectionLimitReached = new EventEmitter();
@Output() dropdownClosed = new EventEmitter();
@Output() dropdownOpen = new EventEmitter();
@Output() onAdded = new EventEmitter();
@Output() onRemoved = new EventEmitter();
@HostListener('document: click', ['$event.target'])
onClick(target: HTMLElement) {
if(this.isVisible && !this.element.nativeElement.contains(target)) {
this.isVisible = false;
this.dropdownClosed.emit();
} else if(this.element.nativeElement.querySelector('button').contains(target)) {
this.dropdownOpen.emit();
}
}
model: Array<IMultiSelectOption>;
title: string;
differ: any;
numSelected: number = 0;
isVisible: boolean = false;
searchFilterText: string = '';
isCheckedAll:boolean = false;
fewChecked:boolean = false;
defaultSettings: IMultiSelectSettings = {
pullRight: false,
enableSearch: true,
checkedStyle: 'checkboxes',
buttonClasses: 'btn btn-default btn-secondary',
selectionLimit: 0,
closeOnSelect: false,
autoUnselect: false,
showCheckAll: true,
showUncheckAll: true,
dynamicTitleMaxItems: 1,
maxHeight: '300px',
};
defaultTexts: IMultiSelectTexts = {
checkAll: 'Check all',
uncheckAll: 'Uncheck all',
checked: 'checked',
checkedPlural: 'checked',
searchPlaceholder: 'Search...',
defaultTitle: 'Select',
allSelected: 'All selected',
};
constructor(
private element: ElementRef,
private differs: IterableDiffers,
private cd:ChangeDetectorRef,
private zone:NgZone) {
this.differ = differs.find([]).create(null);
}
dataSetUpdated(optts){
this.options = optts;
// this.searchFilterText = optts;
console.log("MOHIT",this.model)
}
getItemStyle(option: IMultiSelectOption): any {
if (!option.isLabel) {
return {'cursor': 'pointer'};
}
}
toggleCheckAll() {
this.isCheckedAll = !this.isCheckedAll;
this.fewChecked = false;
if( this.isCheckedAll ) {
this.checkAll();
} else {
this.uncheckAll();
}
}
ngOnInit() {
this.settings = Object.assign(this.defaultSettings, this.settings);
this.texts = Object.assign(this.defaultTexts, this.texts);
this.title = this.texts.defaultTitle || '';
this.options = this.options || [];
}
onModelChange: Function = (_: any) => {};
onModelTouched: Function = () => {};
writeValue(value: any): void {
if ( value ) {
this.model = value;
// this.updateNumSelected();
// this.updateTitle();
// this.setCircleStatus();
}
}
registerOnChange(fn: Function): void {
this.onModelChange = fn;
}
registerOnTouched(fn: Function): void {
this.onModelTouched = fn;
}
setDisabledState(isDisabled: boolean) {
this.disabled = isDisabled;
}
ngDoCheck() {
const modelChanges = this.differ.diff(this.model);
const optionsChanges = this.differ.diff(this.options);
// if (modelChanges || optionsChanges) {
// this.updateNumSelected();
// this.updateTitle();
// this.setCircleStatus();
// }
}
validate(c: AbstractControl): { [key: string]: any; } {
return (this.model && this.model.length) ? null : {
required: {
valid: false,
},
};
}
registerOnValidatorChange(fn: () => void): void {
throw new Error('Method not implemented.');
}
clearSearch(event: Event) {
event.stopPropagation();
this.searchFilterText = '';
}
toggleDropdown() {
this.isVisible = !this.isVisible;
if (!this.isVisible) {
this.dropdownClosed.emit();
}
}
isSelected(option: IMultiSelectOption): boolean {
return this.model && this.model.filter( item => {
return item.key === option.key;
}).length > 0;
}
setSelected(option: IMultiSelectOption) {
if ( !this.model ) {
this.model = [];
}
//const index = this.model.indexOf(option);
let index = -1;
this.model.forEach( (item, idx) => {
if( item.key === option.key ) {
index = idx;
return;
}
});
if ( index > -1 ) {
this.model.splice(index, 1);
this.onRemoved.emit(option);
} else {
this.model.push(option);
this.onAdded.emit(option);
}
if (this.settings.closeOnSelect) {
this.toggleDropdown();
}
this.onModelChange(this.model);
this.onModelTouched();
this.setCircleStatus();
//this.updateNumSelected();
}
setCircleStatus() {
console.log("this.ng2_multiselect_child called");
if( !this.model ) return;
if(this.model.length === 0) {
this.fewChecked = false;
this.isCheckedAll = false;
} else if(this.options.length > this.model.length) {
this.fewChecked = true;
this.isCheckedAll = false;
} else if(this.options.length === this.model.length) {
this.isCheckedAll = true;
this.fewChecked = false;
}
}
updateNumSelected() {
this.numSelected = this.model && this.model.length || 0;
}
updateTitle() {
if(this.model && this.model.length > 0) {
this.title = this.model[0].value;
} else {
this.title = this.texts.defaultTitle;
}
}
checkAll() {
this.model = this.model || [];
this.model = this.options
.map((option: IMultiSelectOption) => {
if (this.model.indexOf(option) === -1) {
this.onAdded.emit(option);
}
return option;
});
this.onModelChange(this.model);
// this.updateNumSelected();
// this.updateTitle();
this.onModelTouched();
}
uncheckAll() {
console.log("UNCHECKED ALL CALLED");
this.model = this.model || [];
this.model.forEach((option: IMultiSelectOption) => this.onRemoved.emit(option));
this.model = [];
this.onModelChange(this.model);
// this.updateNumSelected();
// this.updateTitle();
this.onModelTouched();
}
preventCheckboxCheck(event: Event, option: IMultiSelectOption) {
if (this.settings.selectionLimit &&
this.model.length >= this.settings.selectionLimit &&
this.model.indexOf(option) === -1
) {
event.preventDefault();
}
}
}
@NgModule({
imports: [CommonModule, FormsModule],
exports: [MultiselectDropdown, MultiSelectSearchFilter],
declarations: [MultiselectDropdown, MultiSelectSearchFilter],
})
export class MultiselectDropdownModule {
}