@randstad-design/orbit-multitheme
Version:
multitheme Front-end code based on Randstad Human Forward components
162 lines (145 loc) • 3.82 kB
JavaScript
/**
* share-price.js
* display share information
*/
import { format } from 'date-fns'
/**
* Declare constants
*/
const attributeBase = 'data-rs-share-price';
export class SharePrice {
constructor(element) {
this.feed = 'https://tools.eurolandir.com/tools/pricefeed/?companycode=nl-rand';
this.element = element;
this.getFeed().then((result) => {
this.result = result;
this.renderResult();
}).catch((reason) => {
console.error(reason);
})
}
get attributes() {
return {
value: `${attributeBase}-value`
}
}
get classes() {
return {
change: {
up: 'share-price--change-up',
down: 'share-price--change-down'
}
}
}
/**
* Get XML feed with share price information
* @see https://tools.eurolandir.com/tools/pricefeed/?companycode=nl-rand
*/
getFeed() {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let result = null;
// parse to xml
try {
const parser = new DOMParser();
result = parser.parseFromString(xhr.responseText, 'text/xml');
} catch (error) {
reject(error);
}
resolve(result);
} else {
reject(xhr.statusText);
}
}
};
xhr.open('GET', this.feed, true);
xhr.send();
})
}
/**
* render results to placeholder elements
*/
renderResult() {
const changeValue = this.getResultValue('Change');
// add class to container if change is up or down
this.element.classList.add(SharePrice.changeIsUp(changeValue)
? this.classes.change.up
: this.classes.change.down);
// render seperate items
this.renderResultItem('last', this.getResultValue('Last', SharePrice.formatCurrency));
const change = `${SharePrice.formatChange(changeValue)} (${this.getResultValue('ChangePercent', SharePrice.formatNumber)} %)`;
this.renderResultItem('change', change);
this.renderResultItem('low', this.getResultValue('Low', SharePrice.formatCurrency));
this.renderResultItem('high', this.getResultValue('High', SharePrice.formatCurrency));
this.renderResultItem('symbol', this.getResultValue('Symbol'));
this.renderResultItem('date', this.getResultValue('Date', SharePrice.formatDate));
}
/**
* get result by given key and format value if formatter function is defined
* @param {string} key
* @param {function} formatter
*/
getResultValue(key, formatter) {
let value = this.result.getElementsByTagName(key)[0].textContent;
if (typeof formatter === 'function') {
value = formatter.call(this, value);
}
return value;
}
/**
* render given result item to mapped placeholder element
* @param {string} attributeValue
* @param {string} value
*/
renderResultItem(attributeValue, value) {
this.element.querySelector(`[${this.attributes.value}='${attributeValue}']`).innerText = value;
}
/**
* check if change is up
* @param {string} changeValue
*/
static changeIsUp(changeValue) {
return changeValue.indexOf('-') === -1;
}
/**
* format change
* @param {string} value
*/
static formatChange(value) {
const prefix = value.indexOf('-') === -1
? '+'
: '';
return `${prefix} ${SharePrice.formatNumber(value)}`;
}
/**
* format number
* @param {string} value
*/
static formatNumber(value) {
return value.substring(0, value.length - 2);
}
/**
* format currency
* @param {string} value
*/
static formatCurrency(value) {
return `€ ${SharePrice.formatNumber(value)}`;
}
/**
* format date
* @param {string} value
*/
static formatDate(value) {
value = value.replace(/-/g, '/'); // required for ie11
return format(new Date(value), 'D MMM, HH:mm') + ' CET';
}
/**
* Get selector
*/
static getSelector() {
return `[${attributeBase}]`;
}
}