/**
* @module meteoJS/timeline/navigationButtons
*/
import addEventFunctions from '../Events.js';
/**
* Determines how the time is chosen, when a button for time navigation is
* clicked. On "exact" the time in the timeline is only changed if the time
* exists. In all other cases the time will be changed and a suitable timestamp
* is chosen.
*
* @typedef {"exact"|"nearest"|"before"|"later"}
* module:meteoJS/timeline/navigationButtons~findTimeBy
*/
/**
* Options for constructor.
*
* @typedef {Object} module:meteoJS/timeline/navigationButtons~options
* @param {module:meteoJS/timeline.Timeline} timeline - Timeline object.
* @param {module:meteoJS/timeline/navigationButtons~findTimeBy} findTimeBy
* Determines how the time is chosen, when a button is clicked.
* @param {string|undefined} buttonClass - Default button class.
*/
/**
* @typedef {Object} module:meteoJS/timeline/navigationButtons~buttonDefinition
* @param {string|undefined} [buttonClass] - Class.
* @param {"first"|"last"|"prev"|"next"|"nextAllEnabled"|"prevAllEnabled"|"add"|"sub"}
* methodName - Method to execute on timeline, when button is clicked.
* @param {integer} [timeAmount] - Required when methodName is "add" or "sub."
* @param {string} [timeKey] - Required when methodName is "add" or "sub."
* @param {string} [text] - Text for button.
* @param {string} [title] - Title for button.
*/
/**
* @event module:meteoJS/timeline/navigationButtons#click:button
* @type {module:meteoJS/timeline/navigationButtons~buttonDefinition}
* @property {boolean} isTimeChanged - Time changed.
* @property {external:HTMLElement} button - Button.
* @property {"first"|"last"|"prev"|"next"|"nextAllEnabled"|"prevAllEnabled"|"add"|"sub"}
* methodName - Method executed on timeline.
* @property {integer} [timeAmount] - Passed if methodName is "add" or "sub."
* @property {string} [timeKey] - Passed if methodName is "add" or "sub."
*/
/**
* Class to create buttons and insert them into the DOM to navigate
* through the times of the passed timeline.
*
* <pre><code>import NavigationButtons from 'meteojs/timeline/NavigationButtons';</code></pre>
*
* @fires module:meteoJS/timeline/navigationButtons#click:button
*/
export class NavigationButtons {
/**
* @param {module:meteoJS/timeline/navigationButtons~options} [options]
* Options.
*/
constructor({ timeline,
findTimeBy = 'exact',
buttonClass,
} = {}) {
/**
* @type module:meteoJS/timeline.Timeline
* @private
*/
this.timeline = timeline;
/**
* @type module:meteoJS/timeline/navigationButtons~findTimeBy
* @private
*/
this.findTimeBy = findTimeBy;
/**
* @type string|undefined
* @private
*/
this.buttonClass = buttonClass;
}
/**
* Creates button HTMLElements and append them to the passed node.
*
* @param {external:HTMLElement|external:jQuery} node - Node to insert the buttons into it.
* @param {...module:meteoJS/timeline/navigationButtons~buttonDefinition}
* buttons - Button defintions to insert.
*/
insertButtonInto(node, ...buttons) {
buttons.forEach(({ buttonClass,
methodName,
timeAmount,
timeKey,
text,
title } = {}) => {
if (!/^(first|last|prev|next|nextAllEnabled|prevAllEnabled|add|sub)$/
.test(methodName))
return;
if (text === undefined)
switch (methodName) {
case 'first':
text = '|«';
break;
case 'last':
text = '»|';
break;
case 'prev':
text = '«';
break;
case 'next':
text = '»';
break;
case 'nextAllEnabled':
text = '»';
break;
case 'prevAllEnabled':
text = '«';
break;
case 'add':
text = `+${timeAmount}${timeKey}`;
break;
case 'sub':
text = `-${timeAmount}${timeKey}`;
break;
}
let button = document.createElement('button');
button.appendChild(document.createTextNode(text));
button.setAttribute('type', 'button');
if (typeof buttonClass == 'string')
buttonClass.split(' ').map(c => button.classList.add(c));
else if (typeof this.buttonClass == 'string')
this.buttonClass.split(' ').map(c => button.classList.add(c));
if (title !== undefined)
button.setAttribute('title', title);
button.addEventListener('click', () => {
let isTimeChanged = true;
let oldSelectedTime = this.timeline.getSelectedTime();
switch (methodName) {
case 'add':
this.timeline.add(timeAmount, timeKey);
if (this.timeline.getSelectedTime().valueOf() ==
oldSelectedTime.valueOf())
isTimeChanged = false;
break;
case 'sub':
this.timeline.sub(timeAmount, timeKey);
if (this.timeline.getSelectedTime().valueOf() ==
oldSelectedTime.valueOf())
isTimeChanged = false;
break;
default:
this.timeline[methodName]();
}
this.trigger('click:button', {
isTimeChanged,
button,
methodName,
timeAmount,
timeKey
});
});
if (node.jquery)
node[0].appendChild(button);
else
node.appendChild(button);
});
}
}
addEventFunctions(NavigationButtons.prototype);
export default NavigationButtons;