File

app/dxa/dxa-entity/views/product-info-views/product-info-main/product-info-main.component.ts

Implements

OnInit

Metadata

changeDetection ChangeDetectionStrategy.OnPush
selector div[product-info-main]
styleUrls ./product-info-main.component.scss
templateUrl ./product-info-main.component.html

Index

Properties
Methods
Inputs
HostBindings

Constructor

constructor(linkService: ComponentLinkService, util: UtilService, idGenerator: IdGeneratorService)
Parameters :
Name Type Optional
linkService ComponentLinkService No
util UtilService No
idGenerator IdGeneratorService No

Inputs

entity

HostBindings

class

Methods

Private formatImageVideo
formatImageVideo(imageVideo)
Parameters :
Name Optional
imageVideo No
Returns : { url: any; altText: any; type: any; mimeType: any; }
ngOnInit
ngOnInit()
Returns : void
Private parseEntity
parseEntity()
Returns : { description: any; columnOne: any; columnTwo: any; ctaButtonLinks: any; imageVideoLinks: any; }

Properties

Public carouselId
Default value : 'a' + ('' + this.idGenerator.getId()).slice(2)
Public data
Type : ProductInfoData
import { Component, OnInit, Input, ViewChild, ChangeDetectionStrategy, HostBinding } from '@angular/core';
import { UtilService } from 'src/app/core/services/util-service/util.service';
import { ComponentLinkService } from 'src/app/core/services/component-link-service/component-link.service';
import { IdGeneratorService } from 'src/app/core/services/id-generator.service';
import { ComponentLink } from 'src/app/core/interfaces/interfaces.component';

interface ProductInfoData {
	description: string;
	columnOne: string;
	columnTwo: string;
	ctaButtonLinks: ComponentLink[];
	imageVideoLinks;
}

@Component({
	selector: 'div[product-info-main]',
	templateUrl: './product-info-main.component.html',
	styleUrls: ['./product-info-main.component.scss'],
	changeDetection: ChangeDetectionStrategy.OnPush
})
export class ProductInfoMainComponent implements OnInit {

	@Input() entity;

	public data: ProductInfoData;
	// cannot be just a number, and canot include decimal point
	public carouselId = 'a' + ('' + this.idGenerator.getId()).slice(2);

	@HostBinding('class') get class() { return 'col-md-12 space-between'; }

	constructor(private linkService: ComponentLinkService,
				private util: UtilService,
				private idGenerator: IdGeneratorService
	) { }

	ngOnInit() {
		if (this.entity) {
			this.data = this.parseEntity();
		}
	}

	private parseEntity() {

		const links = this.util.extract(this.entity, 'CtaLinks') || [];
		const resolvedImageVideoLinks = (this.util.extract(this.entity, 'ImageVideo') || []).map(imageVideo => this.formatImageVideo(imageVideo));

		return  {
			description: this.util.extract(this.entity, 'Description', 'BodyText'),
			columnOne: this.util.extract(this.entity, 'ColumnOne'),
			columnTwo: this.util.extract(this.entity, 'ColumnTwo'),
			ctaButtonLinks:  links.map(link => this.linkService.parseLink(link)),
			imageVideoLinks: resolvedImageVideoLinks
		};

	}


	private formatImageVideo(imageVideo) {
		const url = this.util.extract(imageVideo, 'Url');
		const mimeType = this.util.extract(imageVideo, 'MimeType');
		// type should be image or video
		const type = mimeType ? mimeType.split('/')[0] : undefined;
		const altText = this.util.extract(imageVideo, 'Assetmetadata', 'Cmsdescription') || '';

		const formated = {
			url: url,
			altText: altText,
			type: type,
			mimeType: mimeType
		};
		return formated;
	}

}
<div class="product-info row" *ngIf="data">
  <div class="col-md-5 col-sm-12">
    <div [id]="carouselId" class="carousel slide skf-carousel" data-interval="false">
      <ol class="carousel-indicators" *ngIf="data.imageVideoLinks.length > 1">
        <li *ngFor="let item of data.imageVideoLinks; let i = index" [attr.data-target]="'#' + carouselId"
          [attr.data-slide-to]="i" [ngClass]="{'active': i === 0}"></li>
      </ol>
      <div class="carousel-inner">
        <div *ngFor="let item of data.imageVideoLinks; let i = index" [ngClass]="{'carousel-item': true, 'active': i === 0}">
          <img *ngIf="item.type === 'image'" [src]="item.url" [alt]="item.altText" class="d-block w-100">
          <video *ngIf="item.type === 'video'" controls="controls" class="d-block w-100"> 
              <source [src]="item.url" [type]="item.mimeType" />
          </video>
        </div>
        <a class="carousel-control-prev" [href]="'#' + carouselId" role="button" data-slide="prev" *ngIf="data.imageVideoLinks.length > 1">
          <span class="skf-carousel-control-prev-icon icon-chevronLarge-back" aria-hidden="true"></span>
        </a>
        <a class="carousel-control-next" [href]="'#' + carouselId" role="button" data-slide="next" *ngIf="data.imageVideoLinks.length > 1">
          <span class="skf-carousel-control-next-icon icon-chevronLarge-next" aria-hidden="true"></span>
        </a>
      </div>
    </div>
  </div>
  <div class="content-area col-md-7 col-sm-12">

    <div class="description" *ngIf="data.description">
      <rich-text-field [body]="data.description"> </rich-text-field>
    </div>

    <div class="d-flex flex-wrap button-wrapper">

      <ng-container *ngFor="let link of data.ctaButtonLinks">
        <a component-link [linkObject]="link.linkObject" class="mr-1 mb-1 btn btn-green component-link" *ngIf="link.linkObject">
          {{ link.title }}
        </a>
      </ng-container>

    </div>

    <div class="columns">

      <!-- No ngIf here so that column two is moved to the right even if column one is not set in the cms -->
      <div class="column-one">
        <rich-text-field [body]="data.columnOne"> </rich-text-field>
      </div>

      <div class="column-two" *ngIf="data.columnTwo">
        <rich-text-field [body]="data.columnTwo"> </rich-text-field>
      </div>

    </div>

  </div>

</div>

./product-info-main.component.scss

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

.product-info {

    .content-area {

        .description {
            padding: 2% 0%;
        }
        
        .columns {
            display: flex;
            flex-wrap: wrap;
            padding: 2% 0%;

            // 50% width in desktop so they are side by side, 100% in mobile so that they are stacked
            .column-one {
                width: 50%;
                @include media-breakpoint-down(md) {
                    width: 100%;
                }
            }
            .column-two {
                width: 50%;
                @include media-breakpoint-down(md) {
                    width: 100%;
                }
            }
        }
    }
}


.button-wrapper {
    @include media-breakpoint-down(md) {
        justify-content: space-between;
    }
    .component-link {
        padding: calc-rem(8) calc-rem(30);
        @include media-breakpoint-down(md) {
            // 48% so that we have some space between
            width: 48%;

            // if the totalt number of buttons is odd then the last button should be full width
            &:last-child:nth-child(odd) {
                width: 100%;
            }
        }
    }

}

.carousel {
    padding-left: 50px;
    padding-right: 50px;
    padding-bottom: 50px;

    .carousel-indicators li {
        width: 10px;
        height: 10px;
        background-color: $light-green;
    }
    .carousel-indicators .active {
        background-color: $light-slate;
    }

    .carousel-control-prev, .carousel-control-next {
        height: unset;
        width: unset;

        .skf-carousel-control-prev-icon, .skf-carousel-control-next-icon{
            color: black;
            @include font-size(45);
        }
    }

}
Legend
Html element
Component
Html element with directive

result-matching ""

    No results matching ""