Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { Component, Input, OnInit, ViewChild, EventEmitter, ElementRef, HostListener } from '@angular/core';
- import { FormGroup } from '@angular/forms';
- import { Subject } from 'rxjs/Subject';
- import { LanguageService } from '../../../services/language/language.service';
- import { COUNTRY_PHONE_VALUES } from '../../../settings/constants/country-list.constants';
- @Component({
- selector: 'adj-dropdown',
- templateUrl: 'dropdown.html',
- })
- export class DropdownComponent implements OnInit {
- @ViewChild('optionsCont') optionsCont: any;
- @ViewChild('filterInputElement') filterInputElement: any;
- @ViewChild('filterableDataContainer') filterableDataContainer: any;
- @ViewChild('unfilterableDataContainer') unfilterableDataContainer: any;
- @Input() element: any;
- @Input() formGroup: FormGroup;
- wasInside: any;
- onChange = new EventEmitter();
- onBlur = new EventEmitter();
- onFocus = new EventEmitter();
- public selectedOption: any = null;
- public isOpen = false;
- public isFocused = false;
- public filterString = '';
- public filteredOptions: Array<any> = [];
- public optionsOrientationUp = false;
- private writtenStringTofocuseOption = '';
- public blur$ = new Subject();
- static countryIsSorted = false;
- constructor(
- public languageService: LanguageService,
- public el: ElementRef
- ) { }
- ngOnInit() {
- if (this.element && this.element.options) {
- if (this.element.control) this.element.control.markAsPristine();
- if (DropdownComponent.countryIsSorted && (this.element.key === 'country' || this.element.key === 'countryCode')) {
- this.sortOptionsValueStings(this.element.options);
- }
- this.languageService.readyStateSubject
- .filter(value => value).subscribe(() => {
- this.element.options.filter((option: any) => option.label && option.label.langId)
- .map((option: any) => option.label)
- .forEach(this.languageService.AddObservable.bind(this.languageService));
- if (this.element.key === 'country' || this.element.key === 'countryCode') {
- this.sortOptionsValueStings(this.element.options);
- DropdownComponent.countryIsSorted = true;
- }
- });
- this.filteredOptions = this.element.options;
- if (this.element.formItem || this.element.control) {
- (this.element.formItem || this.element.control)
- .valueChanges
- .subscribe((value: any) => this.setValue(value, false));
- }
- if (this.element.control && this.element.control.value !== this.element.value) {
- const foundValue = this.element.options.filter((value: any) => value.value === this.element.control.value)[0];
- this.setOption(foundValue);
- }
- }
- this.blur$.do(() => this.isFocused = false)
- .debounceTime(200)
- .filter(() => !this.isFocused)
- .subscribe(() => this.blur());
- this.setDefault();
- }
- @HostListener('click')
- clickInside() {
- this.wasInside = true;
- }
- @HostListener('document:click')
- clickout() {
- if (!this.wasInside) {
- this.blur$.next();
- }
- this.wasInside = false;
- }
- sortOptionsValueStings(options: any[]) {
- options.sort((a: any, b: any) => {
- if (a.label.valueString.toLowerCase().trim() < b.label.valueString.toLowerCase().trim()) {
- return -1;
- } else if (a.label.valueString.toLowerCase().trim() > b.label.valueString.toLowerCase().trim()) {
- return 1;
- } else {
- return 0;
- }
- });
- }
- setDefault() {
- if (this.selectedOption) return;
- const defaultOption = this.element.value
- ? this.element.options.filter((option: any) => option.value === this.element.value)
- : this.element.options;
- if (!defaultOption || !defaultOption.length) return;
- this.setOption(defaultOption[0]);
- }
- setValue(value: any, emit: boolean = true) {
- const option = this.element.options.filter((r: any) => r && r.value).filter((opt: any) => {
- if (value) return opt.value.toString() === value.toString();
- });
- if (option.length) {
- this.setOption(option[0], emit);
- }
- }
- setOption(option: any, emit: boolean = true) {
- if (!option) return;
- this.selectedOption = option ? option : this.selectedOption;
- this.element.value = option.value;
- if (emit) {
- this.element.control = this.element.control ? this.element.control : this.formGroup.controls[this.element.key];
- if (this.element && this.element.control) {
- if (this.element.value === this.formGroup.controls[this.element.key].value) {
- return;
- }
- this.element.control.setValue(option.value);
- }
- this.onChange.emit(this.selectedOption.value);
- if (option.value && this.element && this.element.control) this.element.control.markAsDirty();
- }
- }
- itemSelect(option: any, emit: boolean = true) {
- this.setOption(option, emit);
- this.blur$.next();
- }
- blur(): void {
- this.isFocused = this.isOpen = false;
- this.onBlur.emit();
- }
- focus(event: any) {
- const target = event.srcElement || event.target;
- if (this.element && this.element.params && this.element.params.disabled) return;
- if (target.classList.value === 'open' && this.isOpen) {
- this.blur();
- return;
- }
- this.onFocus.emit();
- if (this.element.control) {
- this.element.control.markAsTouched();
- this.element.control.markAsDirty();
- }
- this.isOpen = true;
- this.isFocused = true;
- this.setOptionsOrientation();
- this.scrollToActive();
- if (this.element && this.element.params && this.element.params.filter) {
- setTimeout(() => {
- if (!this.filterInputElement) return;
- this.filterInputElement.nativeElement.focus();
- this.isFocused = true;
- }, 50);
- }
- }
- scrollToActive() {
- setTimeout(() => {
- if (this.el.nativeElement.classList.contains('active') || this.el.nativeElement.querySelector('div span.active')) {
- const scrollElement = this.el.nativeElement.querySelector('div span.active').offsetTop;
- this.el.nativeElement.querySelector('div').scrollTop = scrollElement;
- }
- }, 10);
- }
- // indent moving on dropdown list
- moveList(arg: any) {
- setTimeout(() => {
- if (this.el.nativeElement.classList.contains('active') || this.el.nativeElement.querySelector('div span.active')) {
- const scrollElement = this.el.nativeElement.querySelector('div span.active').offsetTop;
- const scrollElementHeight = this.el.nativeElement.querySelector('div span.active').offsetHeight;
- const scrollBlock = this.el.nativeElement.querySelector('div').scrollTop;
- if (scrollElement + scrollElementHeight > scrollBlock + this.el.nativeElement.querySelector('div').offsetHeight && arg === 'dn') {
- this.el.nativeElement.querySelector('div').scrollTop = this.el.nativeElement.querySelector('div').scrollTop + scrollElementHeight;
- } else if (scrollElement < scrollBlock && arg === 'up') {
- this.el.nativeElement.querySelector('div').scrollTop = this.el.nativeElement.querySelector('div').scrollTop - scrollElementHeight;
- }
- }
- }, 10);
- }
- setOptionsOrientation() {
- if (!this.optionsCont) return;
- const position = this.optionsCont.nativeElement.getBoundingClientRect();
- this.optionsOrientationUp = position.bottom > 700;
- }
- filter(event: any) {
- if (event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 13) {
- this.arrows(event);
- } else {
- const newFilteredOptions = this.filteredOptions.filter((option: any) => {
- const value = option.label.valueString
- ? option.label.valueString
- : this.languageService.GetLangvalue(option.label.langId);
- return value.toString().toLowerCase().indexOf(this.filterString.toLowerCase()) === 0;
- });
- this.setOption(newFilteredOptions[0]);
- this.element.options = newFilteredOptions;
- this.el.nativeElement.querySelector('div').scrollTop = 0;
- }
- }
- kd(event: any) {
- event.preventDefault();
- event.stopPropagation();
- }
- arrows(event: any) {
- if (!this.isFocused) { return; }
- this.kd(event);
- let gotOne: any;
- switch (event.keyCode || event.which) {
- case 38: // up
- let prevOption: any;
- this.element.options.forEach((option: any, i: number) => {
- if (gotOne) return;
- if (option.value === this.selectedOption.value) {
- gotOne = true;
- this.setOption(prevOption);
- this.moveList('up');
- return;
- }
- prevOption = this.element.options[i];
- });
- break;
- case 40: // down
- let getNext: any;
- this.element.options.forEach((option: any, i: number) => {
- if (gotOne) return;
- if (option.value === this.selectedOption.value) {
- getNext = true;
- return;
- }
- if (getNext) {
- this.setOption(this.element.options[i]);
- this.moveList('dn');
- gotOne = true;
- }
- });
- break;
- case 13: // enter
- this.blur();
- break;
- case 9: // tab
- const nextElement = Object.keys(this.element.control.parent.controls)
- .filter(key => this.element.control.parent.controls[key].element.order === this.element.order + 1)
- .map(key => this.element.control.parent.controls[key])[0];
- this.blur();
- break;
- default: // typing when dropdown open and not has filter
- if (!this.element.params && this.element.params['keyFilter'] === undefined) { return; }
- this.writtenStringTofocuseOption += event.key === 'Shift' ? '' : event.key;
- const matchingOption = this.filteredOptions.filter((option: any) => {
- if (option['label'] !== undefined) {
- const value = option.label.valueString
- ? option.label.valueString
- : this.languageService.GetLangvalue(option.label.langId);
- return value.toString().toLowerCase().indexOf(this.writtenStringTofocuseOption.toLowerCase()) === 0;
- } else {
- return option.value.toString().toLowerCase().indexOf(this.writtenStringTofocuseOption.toLowerCase()) === 0;
- }
- });
- if (matchingOption.length && matchingOption['value'] !== '') {
- if (matchingOption['value'] === this.writtenStringTofocuseOption) {
- this.writtenStringTofocuseOption = '';
- } else {
- this.setOption(matchingOption[0]);
- this.scrollToActive();
- }
- } else {
- this.setOption(this.filteredOptions[0]);
- this.scrollToActive();
- this.writtenStringTofocuseOption = event.key;
- }
- break;
- }
- }
- changeToCountryCode(value: any) {
- const filtered = COUNTRY_PHONE_VALUES.filter(s => s.c.toString() === value.toString())[0];
- return filtered ? filtered.m : '';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement