File

app/sitesearch/shared/facet-hierarchy/facet-hierarchy.component.ts

Implements

OnInit OnChanges OnDestroy

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector hierarchy-facet
styleUrls ./facet-hierarchy.component.scss
templateUrl ./facet-hierarchy.component.html

Index

Properties
Methods
Inputs

Constructor

constructor(loadingService: LoadingIndicatorService, changeRef: ChangeDetectorRef, labelService: LabelService, tcmResolver: TcmResolverService)
Parameters :
Name Type Optional
loadingService LoadingIndicatorService No
changeRef ChangeDetectorRef No
labelService LabelService No
tcmResolver TcmResolverService No

Inputs

facet
stats

Methods

Public buildBreadcrumb
buildBreadcrumb(filters)

Builds breadcrumb

Parameters :
Name Optional
filters No
Returns : void
Public findLowestBranch
findLowestBranch(cat)

Recursively go through category tree and find lowest first node which has more than 1 child.

If you've gone through the whole tree without finding one (no children left), select lowest branch.

Parameters :
Name Optional
cat No
Returns : void
Public findSelectedCat
findSelectedCat(filters)

Recursively find selected filter

Parameters :
Name Optional
filters No
Returns : any
ngOnChanges
ngOnChanges(changes: SimpleChanges)
Parameters :
Name Type Optional
changes SimpleChanges No
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Public selectFilter
selectFilter(filter)
Parameters :
Name Optional
filter No
Returns : void
Public toggleFacet
toggleFacet()

Toggle facet div

Returns : void
Public trackFilters
trackFilters(index, filter)
Parameters :
Name Optional
index No
filter No
Returns : any

Properties

breadcrumb
Type : []
Default value : []
Public changeRef
Type : ChangeDetectorRef
facetNameLabel
Type : string
filterList
Type : []
Default value : []
Public labelService
Type : LabelService
Public loadingService
Type : LoadingIndicatorService
open
Default value : true
parent
resolvedFilters
Type : []
Default value : []
resolvedIds
selectedCategory
subscription
Type : any
tcmIds
Type : []
Default value : []
import { Component, OnInit, Input, ChangeDetectionStrategy, SimpleChanges, ChangeDetectorRef, OnChanges, OnDestroy } from '@angular/core';
import { LabelService } from 'src/app/core/services/label-service/label-service.service';
import { TcmResolverService } from 'src/app/core/services/tcmResolver.service';
import { LoadingIndicatorService } from 'src/app/core/services/loading-indicator.service';


@Component ({
		selector: 'hierarchy-facet',
		templateUrl: './facet-hierarchy.component.html',
		styleUrls: ['./facet-hierarchy.component.scss'],
		changeDetection: ChangeDetectionStrategy.OnPush
	})
	export class HierarchyFacetComponent implements OnInit, OnChanges, OnDestroy {

		@Input() facet;
		@Input() stats;

		open = true;
		filterList = [];
		resolvedFilters = [];
		parent;
		resolvedIds;
		tcmIds = [];
		breadcrumb = [];
		selectedCategory;
		subscription: any;

		// Label
		facetNameLabel: string;

		constructor(
			public loadingService: LoadingIndicatorService,
			public changeRef: ChangeDetectorRef,
			public labelService: LabelService,
			private tcmResolver: TcmResolverService
		) { }

		ngOnInit() {
			this.labelService.getLabel(this.facet.displayName).then(res => {
				this.facetNameLabel = res;
				this.changeRef.markForCheck();
			});
		}

		ngOnChanges(changes: SimpleChanges): void {
			if (changes) {
				this.tcmIds = [];

				this.buildBreadcrumb(this.facet.filters);

				// If a category has been selected, show its children.
				// Otherwise, find the lowest node which has more than 1 child, and show that instead.
				if (this.selectedCategory) {
					this.filterList = this.selectedCategory.children;
					const isTcm = this.selectedCategory.displayName.match(/\d+-\d+/);
					if (isTcm) { this.tcmIds.push(isTcm.input); }

				} else {
					this.parent = undefined;
					// if (this.facet.filters.length > 1) { this.filterList = this.facet.filters; }
					this.filterList = this.facet.filters;
					// else {
					// 	this.findLowestBranch(this.facet.filters[0]);
					// }
				}

				// Translate displayName of filters if they are tcm-ids.
				this.filterList.forEach(filter => {
					const isTcm = filter.displayName.match(/\d+-\d+/);
					if (isTcm) { this.tcmIds.push(isTcm.input); }
				});

				// If tcm-id was found in filter names, get their real value from tcmResolver.
				if (this.tcmIds.length > 0) {
					const resolver = this.tcmResolver.resolveTcmIds(this.tcmIds);
					this.subscription = resolver.subscribe(ids => {
						this.resolvedIds = ids;
						this.resolvedFilters = this.filterList.map(filter => {
							if (filter.displayName in this.resolvedIds) { filter.resolvedName = this.resolvedIds[filter.displayName]; }
							else { filter.resolvedName = filter.displayName; }
							return filter;
						});

						if (this.selectedCategory) { this.selectedCategory.resolvedName = this.resolvedIds[this.selectedCategory.displayName]; }
						this.changeRef.detectChanges(); // Needed for updating view after names have been resolved.
					});

				} else { // If no tcm-id was found, use filters as they are.
					this.resolvedFilters = this.filterList;
				}

			}
		}

		ngOnDestroy(): void {
			if (this.subscription) { this.subscription.unsubscribe(); }
		}

		public trackFilters(index, filter) {
			return filter ? filter.displayName : {};
		}

		/** Toggle facet div  */
		public toggleFacet() {
			this.open = !this.open;
		}

		/** Recursively find selected filter */
		public findSelectedCat(filters) {
			let foundFilter;

			filters.forEach(filter => {
				if (filter.selected) {
					this.breadcrumb.push(filter);
					foundFilter = filter;
				} else {
					const crumb = this.findSelectedCat(filter.children);
					if (crumb) {
						this.breadcrumb.push(filter);
						foundFilter = filter;
					}
				}
			});

			return foundFilter;
		}

		/** Builds breadcrumb  */
		public buildBreadcrumb(filters) {
			this.breadcrumb = [];
			this.findSelectedCat(filters);

			// Breadcrumb is built backwards, revers to get right order
			this.breadcrumb.reverse();

			if (this.breadcrumb.length > 0) {
				this.selectedCategory = this.breadcrumb[this.breadcrumb.length - 1];
			}

			// If no parent, set parent to self
			if (this.breadcrumb.length === 1) {
				this.parent = this.selectedCategory;
			}
			else if (this.breadcrumb.length > 1) {
				this.parent = this.breadcrumb[this.breadcrumb.length - 2];
			} else {
				this.parent = undefined;
				this.selectedCategory = undefined;
			}

		}

		/** Recursively go through category tree and find lowest
		 *  first node which has more than 1 child.
		 *
		 *  If you've gone through the whole tree without finding one (no children left), select lowest branch.
		 */
		public findLowestBranch(cat) {
			if (cat) {
				const list = cat.children;
				if (list.length > 1 || cat.count !== this.stats.totalHits) {
					this.filterList = cat.children;
				}
				else if (list.length === 0) {
					cat.select();
				}
				else { this.findLowestBranch(list[0]); }
			}
		}

		public selectFilter(filter) {
			this.loadingService.show();
			if (filter === this.selectedCategory) { this.facet.deselect(); }
			else { filter.select(); }
		}

	}
<div class="card">
    <div class="card-header" (click)="parent && selectFilter(parent)">
        <i class="icon-chevronPrev back-parent" [hidden]="!parent"></i>
        <div class="title" *ngIf="selectedCategory">
            {{selectedCategory.resolvedName || selectedCategory.displayName || facetNameLabel}}
        </div>
        <div class="title" *ngIf="!selectedCategory">
            {{ facetNameLabel }}
        </div>
    </div>
    <div class="card-body" *ngIf="resolvedFilters.length > 0">
        <ul class="list-group list-group-flush">
            <li class="list-group-item" *ngFor="let filter of resolvedFilters; let i=index; trackBy: trackFilters" (click)="selectFilter(filter)">
                <label class="list-group-item-name">
                    {{filter.resolvedName || filter.displayName}}
                </label>
                <i class="icon-chevronNext"></i>
            </li>
        </ul>
    </div>
</div>

./facet-hierarchy.component.scss

@import "src/app/styles/helpers";

.card {
    margin-bottom: calc-rem(15);
    color: $light-blue;
    border: none;

    &-header {
        background-color: $cool-grey;
        display: flex;
        flex-direction: row;
        align-items: center;
        padding: calc-rem(20);
        margin-bottom: calc-rem(2);
        @include font-scale(14, uppercase);
        letter-spacing: calc-rem(2);
        border: none;
        cursor: pointer;

        .title {
            text-transform: uppercase;
        }

        .back-parent {
            display: inline-block;
            @include font-size(12);
            margin-right: calc-rem(10);
            margin-top: calc-rem(2);
        }
    }

    &-body {
        background-color: $cool-grey;

        .list-group {

            &-item {
                background-color: transparent;
                color: $light-blue;
                display: flex;
                justify-content: space-between;
                @include font-scale(14, uppercase);
                letter-spacing: calc-rem(2);
                padding: calc-rem(10) 0;
                align-items: center;
                border-color: rgba($light-blue, 0.5);
                cursor: pointer;

                &-name {
                    display: flex;
                    flex-grow: 1;
                    margin: 0;
                    cursor: pointer;
                }

                i {
                    color: $light-blue;
                    @include font-size(14);
                }
            }
        }
    }
}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""