Skip to content

Instantly share code, notes, and snippets.

@Macadoshis
Created January 7, 2019 17:26
Show Gist options
  • Select an option

  • Save Macadoshis/150eb0e87df9eab9988539a9edb5edf4 to your computer and use it in GitHub Desktop.

Select an option

Save Macadoshis/150eb0e87df9eab9988539a9edb5edf4 to your computer and use it in GitHub Desktop.
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, forwardRef, Input, OnChanges, Output, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { DomHandler, SelectItem } from 'primeng/api';
import { ObjectUtils } from 'primeng/components/utils/objectutils';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Checkbox, MultiSelect } from 'primeng/primeng';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { TranslateService } from '@ngx-translate/core';
/**
* Overriding of primeng component "p-multiselect", to display and handle custom UI/UX behaviors.
*
* <b>Disclaimer</b> : in case of "primeng" upgrading or downgrading, make sure you compare both attributes "template" (html content), set in "multiselect.js" file,
* between source and target, and apply all eventual changes in "cmss-p-multiselect.html" file.
*/
@Component({
selector: 'cmss-p-multiSelect',
providers: [
DomHandler,
ObjectUtils,
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => CmssMultiSelect),
multi: true
}],
templateUrl: './cmss-p-multiselect.component.html',
styleUrls: ['./cmss-p-multiselect.component.scss'],
animations: [
trigger('overlayAnimation', [
state('void', style({
transform: 'translateY(5%)',
opacity: 0
})),
state('visible', style({
transform: 'translateY(0)',
opacity: 1
})),
transition('void => visible', animate('225ms ease-out')),
transition('visible => void', animate('195ms ease-in'))
])
],
host: {
'[class.ui-inputwrapper-filled]': 'filled',
'[class.ui-inputwrapper-focus]': 'focus'
}
})
export class CmssMultiSelect extends MultiSelect implements OnChanges {
@Input()
readonly: boolean = false;
@Input()
dataKey: string;
@Input()
disabled: boolean = false;
@ViewChild('cb')
private ckbToggleAll: Checkbox;
private _onApplyFilters: EventEmitter<any> = new EventEmitter();
/** If <code>true</code>, filtered selection has changed but hasn't been applied yet (dirty mode). */
private _filterApplied: boolean = true;
get filterApplied(): boolean {
return this._filterApplied;
}
/** Applied values */
private _appliedValues: any[] = null;
ngOnChanges(changes: SimpleChanges): void {
if (changes['options']) {
this.showToggleAll = this.options && this.options.length > 0;
}
}
/** Outputs filter validation */
@Output()
get onApplyFilters(): EventEmitter<any> {
return this._onApplyFilters;
}
constructor(el: ElementRef, domHandler: DomHandler, renderer: Renderer2, objectUtils: ObjectUtils, cd: ChangeDetectorRef, private translateService: TranslateService) {
super(el, domHandler, renderer, objectUtils, cd);
/** Default common settings (can be overriden if set as @Inputs() */
this.maxSelectedLabels = 3;
this.translateService.get('cmss.selection.selectedItems').subscribe((sil: string) => this.selectedItemsLabel = sil);
this.translateService.get('cmss.search.placeholder').subscribe((ph: string) => this.filterPlaceHolder = ph);
this.translateService.get('cmss.selection.all').subscribe((dl: string) => this.defaultLabel = dl);
}
hasSelection(): boolean {
return this.value && this.value.length > 0;
}
/**
* Clear filters selection (without applying).
*/
clearFilters(event: Event): void {
this.ckbToggleAll.checked = true;
this.toggleAll(event, this.ckbToggleAll);
}
/**
* Apply filters selection.
*/
applyFilters(event: Event, emitApplyFilters: boolean): void {
if (emitApplyFilters) {
this._onApplyFilters.emit({ originalEvent: event, value: this.value });
}
this._filterApplied = true;
if (event) {
this.close(event);
}
this._appliedValues = this.value;
}
writeValue(value: any, emitApplyFilters: boolean = true): void {
super.writeValue(value);
this._filterApplied = false;
this.applyFilters(undefined, emitApplyFilters);
}
onItemClick(event: any, option: any): void {
super.onItemClick(event, option);
this._filterApplied = false;
}
toggleAll(event: any, checkbox: any): void {
super.toggleAll(event, checkbox);
if (this.options && this.options.length > 0) {
// Only mark as touched if there's at least one item in the list (selected or not)
this._filterApplied = false;
}
}
/** Mark filter as applied (in case of external events) */
markFilterApplied(): void {
this._filterApplied = true;
}
onOverlayHide(): void {
super.onOverlayHide();
// If filter has not been applied before closing, resets values to last applied values
if (!this._filterApplied) {
this.writeValue(this._appliedValues, false);
}
}
isItemVisible(option: SelectItem): boolean {
if (this.filterValue && this.filterValue.trim().length) {
for (let i = 0; i < this.visibleOptions.length; i++) {
if (JSON.stringify(this.visibleOptions[i].value) == JSON.stringify(option.value)) {
return true;
}
}
}
else {
return true;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment