Skip to content

Commit

Permalink
Bootstrap 4 is now default style. fixes #379
Browse files Browse the repository at this point in the history
  • Loading branch information
softsimon committed Mar 7, 2018
1 parent 705f870 commit 45eb341
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 105 deletions.
4 changes: 4 additions & 0 deletions src/dropdown/dropdown.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,7 @@ a {
display: table-cell;
vertical-align: middle;
}

.search-container {
padding: 0px 5px 5px 5px;
}
82 changes: 41 additions & 41 deletions src/dropdown/dropdown.component.html
Original file line number Diff line number Diff line change
@@ -1,47 +1,44 @@
<div class="dropdown" [ngClass]="settings.containerClasses" [class.open]="isVisible" (keyup.esc)="closeDropdown($event)"
(keydown.arrowdown)="focusItem(1, $event)" (keydown.arrowup)="focusItem(-1, $event)">
<button *ngIf="!isVisible || !(isVisible && settings.enableSearch); else filter" type="button" class="dropdown-toggle" [ngClass]="settings.buttonClasses"
(click)="toggleDropdown($event)" [disabled]="disabled" [ssAutofocus]="!focusBack">
<div class="dropdown">
<button type="button" class="dropdown-toggle" [ngClass]="settings.buttonClasses" (click)="toggleDropdown($event)" [disabled]="disabled"
[ssAutofocus]="!focusBack">
{{ title }}
<span class="caret"></span>
</button>
<ng-template #filter>
<div class="input-group input-group-sm ">
<span class="input-group-addon " id="sizing-addon3 ">
<i class="fa fa-search "></i>
</span>
<div #scroller *ngIf="isVisible" class="dropdown-menu" [ngClass]="{'chunkydropdown-menu': settings.checkedStyle == 'visual' }"
(scroll)="settings.isLazyLoad ? checkScrollPosition($event) : null" (wheel)="settings.stopScrollPropagation ? checkScrollPropagation($event, scroller) : null"
[class.pull-right]="settings.pullRight" [class.dropdown-menu-right]="settings.pullRight" [style.max-height]="settings.maxHeight"
style="display: block; height: auto; overflow-y: auto;" (keydown.tab)="focusItem(1, $event)" (keydown.shift.tab)="focusItem(-1, $event)">
<div class="input-group search-container" *ngIf="settings.enableSearch">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">
<i class="fa fa-search" aria-hidden="true"></i>
</span>
</div>
<input type="text" class="form-control" ssAutofocus [formControl]="filterControl" [placeholder]="texts.searchPlaceholder"
class="form-control">
<span class="input-group-btn" *ngIf="filterControl.value.length>0">
<div class="input-group-append" *ngIf="filterControl.value.length>0">
<button class="btn btn-default btn-secondary" type="button" (click)="clearSearch($event)">
<i class="fa fa-times"></i>
</button>
</span>
</div>
</div>
</ng-template>
<ul #scroller *ngIf="isVisible" class="dropdown-menu" [ngClass]="{'chunkydropdown-menu': settings.checkedStyle == 'visual' }"
(scroll)="settings.isLazyLoad ? checkScrollPosition($event) : null" (wheel)="settings.stopScrollPropagation ? checkScrollPropagation($event, scroller) : null"
[class.pull-right]="settings.pullRight" [class.dropdown-menu-right]="settings.pullRight" [style.max-height]="settings.maxHeight"
style="display: block; height: auto; overflow-y: auto;" (keydown.tab)="focusItem(1, $event)" (keydown.shift.tab)="focusItem(-1, $event)">
<li class="dropdown-item check-control check-control-check" *ngIf="settings.showCheckAll && !disabledSelection" (click)="checkAll()">
<a role="menuitem" tabindex="-1">
<span style="width: 16px;" [ngClass]="{'glyphicon glyphicon-ok': settings.checkedStyle !== 'fontawesome','fa fa-check': settings.checkedStyle === 'fontawesome'}"></span>
{{ texts.checkAll }}
</a>
</li>
<li class="dropdown-item check-control check-control-uncheck" *ngIf="settings.showUncheckAll && !disabledSelection" (click)="uncheckAll()">
<a role="menuitem" tabindex="-1">
<span style="width: 16px;" [ngClass]="{'glyphicon glyphicon-remove': settings.checkedStyle !== 'fontawesome','fa fa-times': settings.checkedStyle === 'fontawesome'}"></span>
{{ texts.uncheckAll }}
</a>
</li>
<li *ngIf="settings.showCheckAll || settings.showUncheckAll" class="dropdown-divider divider"></li>
<li *ngIf="!renderItems" class="dropdown-item empty">{{ texts.searchNoRenderText }}</li>
<li *ngIf="renderItems && !renderFilteredOptions.length" class="dropdown-item empty">{{ texts.searchEmptyResult }}</li>
<li class="dropdown-item" *ngFor="let option of renderFilteredOptions; trackBy: trackById" [class.active] = "isSelected(option)" [ngStyle]="getItemStyle(option)"
[ngClass]="option.classes" [class.dropdown-header]="option.isLabel" [ssAutofocus]="option !== focusedItem" tabindex="-1"
(click)="setSelected($event, option)" (keydown.space)="setSelected($event, option)" (keydown.enter)="setSelected($event, option)">
<a *ngIf="!option.isLabel; else label" role="menuitem" tabindex="-1" [style.padding-left]="this.parents.length>0&&this.parents.indexOf(option.id)<0&&'30px'"
<a role="menuitem" href="javascript:;" tabindex="-1" class="dropdown-item check-control check-control-check" *ngIf="settings.showCheckAll && !disabledSelection"
(click)="checkAll()">
<span style="width: 16px;" [ngClass]="{'glyphicon glyphicon-ok': settings.checkedStyle !== 'fontawesome','fa fa-check': settings.checkedStyle === 'fontawesome'}"></span>
{{ texts.checkAll }}
</a>
<a role="menuitem" href="javascript:;" tabindex="-1" class="dropdown-item check-control check-control-uncheck" *ngIf="settings.showUncheckAll && !disabledSelection"
(click)="uncheckAll()">
<span style="width: 16px;" [ngClass]="{'glyphicon glyphicon-remove': settings.checkedStyle !== 'fontawesome','fa fa-times': settings.checkedStyle === 'fontawesome'}"></span>
{{ texts.uncheckAll }}
</a>
<a *ngIf="settings.showCheckAll || settings.showUncheckAll" href="javascript:;" class="dropdown-divider divider"></a>
<a *ngIf="!renderItems" href="javascript:;" class="dropdown-item empty">{{ texts.searchNoRenderText }}</a>
<a *ngIf="renderItems && !renderFilteredOptions.length" href="javascript:;" class="dropdown-item empty">{{ texts.searchEmptyResult }}</a>
<a class="dropdown-item" href="javascript:;" *ngFor="let option of renderFilteredOptions; trackBy: trackById" [class.active]="isSelected(option)"
[ngStyle]="getItemStyle(option)" [ngClass]="option.classes" [class.dropdown-header]="option.isLabel" [ssAutofocus]="option !== focusedItem"
tabindex="-1" (click)="setSelected($event, option)" (keydown.space)="setSelected($event, option)" (keydown.enter)="setSelected($event, option)">
<span *ngIf="!option.isLabel; else label" role="menuitem" tabindex="-1" [style.padding-left]="this.parents.length>0&&this.parents.indexOf(option.id)<0&&'30px'"
[ngStyle]="getItemStyleSelectionDisabled()">
<ng-container [ngSwitch]="settings.checkedStyle">
<input *ngSwitchCase="'checkboxes'" type="checkbox" [checked]="isSelected(option)" (click)="preventCheckboxCheck($event, option)"
Expand All @@ -62,11 +59,14 @@
</div>
</span>
</ng-container>
<span [ngClass]="{'chunkyrow': settings.checkedStyle == 'visual' }" [class.disabled]="isCheckboxDisabled(option)" [ngClass]="settings.itemClasses" [style.font-weight]="this.parents.indexOf(option.id)>=0?'bold':'normal'">
<span [ngClass]="{'chunkyrow': settings.checkedStyle == 'visual' }" [class.disabled]="isCheckboxDisabled(option)" [ngClass]="settings.itemClasses"
[style.font-weight]="this.parents.indexOf(option.id)>=0?'bold':'normal'">
{{ option.name }}
</span>
</a>
<ng-template #label><span [class.disabled]="isCheckboxDisabled()">{{ option.name }}</span></ng-template>
</li>
</ul>
</div>
</span>
<ng-template #label>
<span [class.disabled]="isCheckboxDisabled()">{{ option.name }}</span>
</ng-template>
</a>
</div>
</div>
122 changes: 61 additions & 61 deletions src/dropdown/dropdown.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {

const MULTISELECT_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MultiselectDropdown),
useExisting: forwardRef(() => MultiselectDropdownComponent),
multi: true,
};

Expand All @@ -55,13 +55,13 @@ const MULTISELECT_VALUE_ACCESSOR: any = {
providers: [MULTISELECT_VALUE_ACCESSOR, MultiSelectSearchFilter],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class MultiselectDropdown
export class MultiselectDropdownComponent
implements OnInit,
OnChanges,
DoCheck,
OnDestroy,
ControlValueAccessor,
Validator {
OnChanges,
DoCheck,
OnDestroy,
ControlValueAccessor,
Validator {
filterControl: FormControl = this.fb.control('');

@Input() options: Array<IMultiSelectOption>;
Expand All @@ -78,14 +78,14 @@ export class MultiselectDropdown
@Output() onLazyLoad = new EventEmitter();
@Output() onFilter: Observable<string> = this.filterControl.valueChanges;

get focusBack():boolean{
return this.settings.focusBack && this._focusBack
get focusBack(): boolean {
return this.settings.focusBack && this._focusBack;
}

@HostListener('document: click', ['$event.target'])
@HostListener('document: touchstart', ['$event.target'])
onClick(target: HTMLElement) {
if (!this.isVisible || !this.settings.closeOnClickOutside) return;
if (!this.isVisible || !this.settings.closeOnClickOutside) { return; }
let parentFound = false;
while (target != null && !parentFound) {
if (target === this.element.nativeElement) {
Expand Down Expand Up @@ -134,7 +134,7 @@ export class MultiselectDropdown
searchMaxLimit: 0,
searchMaxRenderedItems: 0,
checkedStyle: 'checkboxes',
buttonClasses: 'btn btn-default btn-secondary',
buttonClasses: 'btn btn-primary dropdown-toggle',
containerClasses: 'dropdown-inline',
selectionLimit: 0,
minSelectionLimit: 0,
Expand Down Expand Up @@ -241,7 +241,7 @@ export class MultiselectDropdown
this.settings.selectAddedValues &&
changes.options.previousValue
) {
let addedValues = changes.options.currentValue.filter(
const addedValues = changes.options.currentValue.filter(
value => this.loadedValueIds.indexOf(value.id) === -1
);
this.loadedValueIds.concat(addedValues.map(value => value.id));
Expand All @@ -267,7 +267,7 @@ export class MultiselectDropdown

if (changes['texts']) {
this.texts = { ...this.defaultTexts, ...this.texts };
!changes['texts'].isFirstChange() && this.updateTitle();
if (!changes['texts'].isFirstChange()) { this.updateTitle(); }
}
}

Expand Down Expand Up @@ -304,8 +304,8 @@ export class MultiselectDropdown
}
}

onModelChange: Function = (_: any) => {};
onModelTouched: Function = () => {};
onModelChange: Function = (_: any) => { };
onModelTouched: Function = () => { };

writeValue(value: any): void {
if (value !== undefined && value !== null) {
Expand Down Expand Up @@ -337,20 +337,20 @@ export class MultiselectDropdown
}

validate(_c: AbstractControl): { [key: string]: any } {
if(this.model && this.model.length) {
if (this.model && this.model.length) {
return {
required : {
required: {
valid: false
}
}
};
}

if(this.options.filter(o => this.model.indexOf(o.id) && !o.disabled).length == 0) {
if (this.options.filter(o => this.model.indexOf(o.id) && !o.disabled).length === 0) {
return {
selection : {
selection: {
valid: false
}
}
};
}

return null;
Expand Down Expand Up @@ -458,15 +458,15 @@ export class MultiselectDropdown
addItem(option.id);
if (!isAtSelectionLimit) {
if (option.parentId && !this.settings.ignoreLabels) {
let children = this.options.filter(
const children = this.options.filter(
child =>
child.id !== option.id && child.parentId === option.parentId
);
if (children.every(child => this.model.indexOf(child.id) > -1)) {
addItem(option.parentId);
}
} else if (this.parents.indexOf(option.id) > -1) {
let children = this.options.filter(
const children = this.options.filter(
child =>
this.model.indexOf(child.id) < 0 && child.parentId === option.id
);
Expand Down Expand Up @@ -507,19 +507,19 @@ export class MultiselectDropdown
this.settings.dynamicTitleMaxItems &&
this.settings.dynamicTitleMaxItems >= this.numSelected
) {
let useOptions =
const useOptions =
this.settings.isLazyLoad && this.lazyLoadOptions.length
? this.lazyLoadOptions
: this.options;
? this.lazyLoadOptions
: this.options;

let titleSelections: Array<IMultiSelectOption>;

if (this.settings.maintainSelectionOrderInTitle) {
const optionIds = useOptions.map((selectOption: IMultiSelectOption, idx: number) => selectOption.id);
titleSelections = this.model
.map((selectedId) => optionIds.indexOf(selectedId))
.filter((optionIndex) => optionIndex > -1)
.map((optionIndex) => useOptions[optionIndex]);
const optionIds = useOptions.map((selectOption: IMultiSelectOption, idx: number) => selectOption.id);
titleSelections = this.model
.map((selectedId) => optionIds.indexOf(selectedId))
.filter((optionIndex) => optionIndex > -1)
.map((optionIndex) => useOptions[optionIndex]);
} else {
titleSelections = useOptions.filter((option: IMultiSelectOption) => this.model.indexOf(option.id) > -1);
}
Expand All @@ -545,21 +545,21 @@ export class MultiselectDropdown
}

addChecks(options) {
let checkedOptions = options
.filter(function(option: IMultiSelectOption) {
if (
!option.disabled ||
(
this.model.indexOf(option.id) === -1 &&
!(this.settings.ignoreLabels && option.isLabel)
)
) {
this.onAdded.emit(option.id);
return true;
}
return false;
}.bind(this))
.map((option: IMultiSelectOption) => option.id);
const checkedOptions = options
.filter((option: IMultiSelectOption) => {
if (
!option.disabled &&
(
this.model.indexOf(option.id) === -1 &&
!(this.settings.ignoreLabels && option.isLabel)
)
) {
this.onAdded.emit(option.id);
return true;
}
return false;
})
.map((option: IMultiSelectOption) => option.id);

this.model = this.model.concat(checkedOptions);
}
Expand All @@ -584,7 +584,7 @@ export class MultiselectDropdown

uncheckAll() {
if (!this.disabledSelection) {
let checkedOptions = this.model;
const checkedOptions = this.model;
let unCheckedOptions = !this.searchFilterApplied()
? this.model
: this.filteredOptions.map((option: IMultiSelectOption) => option.id);
Expand All @@ -606,8 +606,8 @@ export class MultiselectDropdown
if (this.searchFilterApplied()) {
if (this.checkAllSearchRegister.has(this.filterControl.value)) {
this.checkAllSearchRegister.delete(this.filterControl.value);
this.checkAllSearchRegister.forEach(function(searchTerm) {
let filterOptions = this.applyFilters(this.options.filter(option => unCheckedOptions.indexOf(option.id) > -1), searchTerm);
this.checkAllSearchRegister.forEach(function (searchTerm) {
const filterOptions = this.applyFilters(this.options.filter(option => unCheckedOptions.indexOf(option.id) > -1), searchTerm);
this.addChecks(filterOptions);
});
}
Expand All @@ -631,7 +631,7 @@ export class MultiselectDropdown
this.model.indexOf(option.id) === -1 &&
this.maybePreventDefault(event)
)
){
) {
this.maybePreventDefault(event);
}
}
Expand All @@ -641,27 +641,27 @@ export class MultiselectDropdown
}

checkScrollPosition(ev) {
let scrollTop = ev.target.scrollTop;
let scrollHeight = ev.target.scrollHeight;
let scrollElementHeight = ev.target.clientHeight;
let roundingPixel = 1;
let gutterPixel = 1;
const scrollTop = ev.target.scrollTop;
const scrollHeight = ev.target.scrollHeight;
const scrollElementHeight = ev.target.clientHeight;
const roundingPixel = 1;
const gutterPixel = 1;

if (
scrollTop >=
scrollHeight -
(1 + this.settings.loadViewDistance) * scrollElementHeight -
roundingPixel -
gutterPixel
(1 + this.settings.loadViewDistance) * scrollElementHeight -
roundingPixel -
gutterPixel
) {
this.load();
}
}

checkScrollPropagation(ev, element) {
let scrollTop = element.scrollTop;
let scrollHeight = element.scrollHeight;
let scrollElementHeight = element.clientHeight;
const scrollTop = element.scrollTop;
const scrollHeight = element.scrollHeight;
const scrollElementHeight = element.clientHeight;

if (
(ev.deltaY > 0 && scrollTop + scrollElementHeight >= scrollHeight) ||
Expand Down
6 changes: 3 additions & 3 deletions src/dropdown/dropdown.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AutofocusDirective } from './autofocus.directive';
import { MultiselectDropdown } from './dropdown.component';
import { MultiselectDropdownComponent } from './dropdown.component';
import { MultiSelectSearchFilter } from './search-filter.pipe';

@NgModule({
imports: [CommonModule, ReactiveFormsModule],
exports: [
MultiselectDropdown,
MultiselectDropdownComponent,
MultiSelectSearchFilter,
],
declarations: [
MultiselectDropdown,
MultiselectDropdownComponent,
MultiSelectSearchFilter,
AutofocusDirective,
],
Expand Down

0 comments on commit 45eb341

Please sign in to comment.