import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, ChangeDetectorRef } from '@angular/core'; import {Filter, Value} from './searchHelperClasses.class'; import {ActivatedRoute, Router} from "@angular/router"; import {SearchFields} from "../../utils/properties/searchFields"; import {HelperFunctions} from "../../utils/HelperFunctions.class"; import {Option} from "../../sharedComponents/input/input.component"; @Component({ selector: 'search-filter', templateUrl: 'searchFilter.component.html' }) export class SearchFilterComponent implements OnInit, OnChanges { @Input() filter: Filter; @Input() showResultCount: boolean = true; @Input() isDisabled: boolean = false; @Input() addShowMore: boolean = true; @Input() showMoreInline: boolean = true; @Input() filterValuesNum: number = 6; public showAll: boolean = false; public _maxCharacters: number = 28; @Output() toggleModal = new EventEmitter(); @Output() modalChange = new EventEmitter(); @Output() onFilterChange = new EventEmitter(); keyword = ""; sortBy: "name" | "num" = "name"; sortByOptions: Option[] = [{label: 'Results number', value: 'num'}, {label: 'Name', value: 'name'}]; queryParams = {}; paramPosition = 0; @Input() actionRoute: boolean = false; @Input() quickFilter: { filter: Filter, selected: boolean, filterId: string, value: string }; sub; public isOpen: boolean = false; sortedValues; hasMatch: boolean = false; constructor(private _router: Router, private route: ActivatedRoute, private cdr: ChangeDetectorRef) { } ngOnDestroy() { if (this.sub) { this.sub.unsubscribe(); } } ngOnInit() { if(this.filterValuesNum == 0){ this.isOpen = true; this.sortBy = "num"; }else{ this.isOpen = false; } this.sub = this.route.queryParams.subscribe(params => { this.queryParams = Object.assign({}, params); this.paramPosition = SearchFields.getParameterOrder(this.filter.filterId, this.getEntries(params)); }); // this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); // this.sort(); // if (this.filter.filterType == "radio") { // this.filter.radioValue = ""; // this.filter.values.forEach(value => { // if (value.selected) { // this.filter.radioValue = value.id // } // }); // } } ngOnChanges(changes: SimpleChanges) { if (changes.filter) { this.filter.values = this.filter.values.filter(value => !value.name.toLowerCase().includes('unknown') && !value.name.toLowerCase().includes('not available')); if (this.filter.filterType == "radio") { this.filter.radioValue = ""; this.filter.values.forEach(value => { if (value.selected) { this.filter.radioValue = value.id } }); } this.sort(); } } public _formatTitle(title, length) { return (((title + " (" + length + ")").length > this._maxCharacters) ? (title.substring(0, (this._maxCharacters - (" (" + length + ")").length - ('...').length)) + "...") : title) + " (" + (length > 95 ? "100" : length) + ")"; } public _formatName(value) { //let maxLineLength = 24; let maxLineLength = 35; //1 space after checkbox //3 space before number + parenthesis if (!this.showResultCount && value.name.length + 1 > maxLineLength) { return value.name.substr(0, maxLineLength - 3 - 1) + '...'; } if (value.name.length + value.number.toLocaleString().length + 1 + 3 > maxLineLength) { return value.name.substr(0, (maxLineLength - 3 - 4 - value.number.toLocaleString().length)) + '...'; } return value.name; } filterKeywords(value) { if (this.keyword.length > 0) { if (value.toLowerCase().indexOf(this.keyword.toLowerCase()) == -1) { return false; } } this.hasMatch = true; return true; } filterChange(selected: boolean) { if (selected) { this.filter.countSelectedValues++; } else { this.filter.countSelectedValues--; } this.onFilterChange.emit({ value: this.filter }); } uniqueFilterChange(value: Value) { let tmp = value.selected; value.selected = !tmp; if (value.selected) { this.filter.countSelectedValues = 1; } else { this.filter.countSelectedValues = 0; } this.filter.values.forEach(value => { value.selected = (value.id == this.filter.radioValue); }); this.onFilterChange.emit({ value: this.filter }); } clearFilter() { for (var i = 0; i < this.filter.values.length; i++) { this.filter.values[i].selected = false; } this.filter.countSelectedValues = 0; this.onFilterChange.emit({ value: this.filter }); this.filter.radioValue = ""; } getSelectedAndTopValues(filter, topNum: number = 6): any { var values = []; for (let i = 0; i < topNum; i++) { if (filter.values.length <= i) { break; } values.push(filter.values[i]); } if (filter.countSelectedValues > 0) { for (let i = topNum; i < filter.values.length; i++) { if (filter.values[i].selected) { values.push(filter.values[i]); } } } return values; } getSelectedValues(filter, sortBy: string = "num"): any { var selected = []; if (filter.countSelectedValues > 0) { for (var i = 0; i < filter.values.length; i++) { if (filter.values[i].selected) { selected.push(filter.values[i]); } } } if (sortBy == "name") { selected.sort((n1, n2) => { if (n1.name > n2.name) { return 1; } if (n1.name < n2.name) { return -1; } return 0; }); } return selected; } getNotSelectedValues(filter, sortBy: string = "num"): any { var notSselected = []; for (var i = 0; i < filter.values.length; i++) { if (!filter.values[i].selected) { notSselected.push(filter.values[i]); } } if (sortBy == "name") { notSselected.sort((n1, n2) => { if (n1.name > n2.name) { return 1; } if (n1.name < n2.name) { return -1; } return 0; }); } return notSselected; } sort() { let sorted: Value[] = this.filter.values.slice(); if (this.sortBy == "name") { sorted.sort((n1, n2) => { if (this.filter.filterId === "sdg") { return HelperFunctions.sortSDGs(n1.name.toLowerCase(), n2.name.toLowerCase()); } else { if (n1.name.toLowerCase() > n2.name.toLowerCase()) { return 1; } if (n1.name < n2.name) { return -1; } return 0; } }); } this.sortedValues = Object.assign(sorted); } initMatching() { this.hasMatch = false; this.cdr.detectChanges(); } toggle(event) { this.isOpen = !this.isOpen; event.stopPropagation(); } disabled(value) { return this.isDisabled || (this.showResultCount && value === 0); } getFilterName(value) { let name = value.name + " (" + value.number.format() + ")"; return name; } getRoute() { return this._router.url.split("?")[0]; } getParams(filter: Filter, value: Value) { let params = Object.assign({}, this.queryParams); /* let qf=false; if(this.quickFilter && this.quickFilter.filterId == filter.filterId && this.quickFilter.selected && value.id == this.quickFilter.value){ params['qf']="false"; qf=true; }*/ if (params[filter.filterId] && this.checkIfValueIndexOf(params[filter.filterId].split(','), value.id) == -1 /*&& !qf*/) { //has other values of this filter --> add this value params[filter.filterId] = params[filter.filterId] + ',' + '"' + encodeURIComponent(value.id) + '"'; } else if (params[filter.filterId] && this.checkIfValueIndexOf(params[filter.filterId].split(','), value.id) != -1) { // has this filter and the value -- > remove it let values = params[filter.filterId].split(','); values.splice(this.checkIfValueIndexOf(values, value.id), 1); params[filter.filterId] = values.join(','); if (values.length == 0) { delete params[filter.filterId]; } } else /*if(!qf)*/{ //has no filter, no value --> add the value //check the order let keyValues = this.getEntries(params); keyValues.splice(this.paramPosition, 0, [filter.filterId, '"' + encodeURIComponent(value.id) + '"']); // insert key value at paramPosition. params = keyValues.reduce((o, key) => Object.assign(o, {[key[0]]: key[1]}), {}); // params[filter.filterId] = '"' + encodeURIComponent(value.id) + '"' ; } delete params['page']; return params; } checkIfValueIndexOf(array, value) { let encodedValue = encodeURIComponent(value); if (array.indexOf(encodedValue) != -1) { return array.indexOf(encodedValue); } if (array.indexOf('"' + encodedValue + '"') != -1) { return array.indexOf('"' + encodedValue + '"'); } return -1; } getEntries(obj) { if (!Object.entries) { var ownProps = Object.keys(obj), i = ownProps.length, resArray = new Array(i); // preallocate the Array while (i--) resArray[i] = [ownProps[i], obj[ownProps[i]]]; return resArray; } else { return Object.entries(obj); } } }