File: D:/HostingSpaces/SBogers10/beerten.komma.nl/vendor/komma/kms/resources/js/attributes/numeric.js
export class Numeric {
constructor(attributeWrapper)
{
if(!attributeWrapper) {
console.log(attributeWrapper);
console.error('Please give the Numeric attdsadsdribute an attribute wrapper "{HTMLElement}"')
}
this.attributeWrapper = attributeWrapper;
this.realInput = this.attributeWrapper.querySelector('.js-real-input');
this.wholeInput = this.attributeWrapper.querySelector('.js-whole');
this.wholeUpButton = this.attributeWrapper.querySelector('.js-whole-up');
this.wholeDownButton = this.attributeWrapper.querySelector('.js-whole-down');
this.fractionInput = this.attributeWrapper.querySelector('.js-fraction'); //Can be falsy when no decimals
this.fractionUpButton = this.attributeWrapper.querySelector('.js-fraction-up'); //Can be falsy when no decimals
this.fractionDownButton = this.attributeWrapper.querySelector('.js-fraction-down'); //Can be falsy when no decimals
this.wholeMin = (this.wholeInput.dataset.min) ? parseInt(this.wholeInput.dataset.min, 10) : null;
this.wholeMax = (this.wholeInput.dataset.max) ? parseInt(this.wholeInput.dataset.max, 10) : null;
this.wholeStep = (this.wholeInput.dataset.step) ? parseInt(this.wholeInput.dataset.step, 10) : null;
this.fractionMin = (this.fractionInput && this.fractionInput.dataset.min) ? parseInt(this.fractionInput.dataset.min, 10) : null;
this.fractionMax = (this.fractionInput && this.fractionInput.dataset.max) ? parseInt(this.fractionInput.dataset.max, 10) : null;
this.fractionStep = (this.fractionInput && this.fractionInput.dataset.step) ? parseInt(this.fractionInput.dataset.step, 10) : null;
this.fractionLength = (this.attributeWrapper.dataset.fractionLength) ? parseInt(this.attributeWrapper.dataset.fractionLength, 10) : null;
this.zeroPadFraction = (this.attributeWrapper.dataset.zeroPadFraction) ? this.attributeWrapper.dataset.zeroPadFraction : false;
this.wholeInputChanged = this.wholeInputChanged.bind(this);
this.wholeUpButtonClicked = this.wholeUpButtonClicked.bind(this);
this.wholeDownButtonClicked = this.wholeDownButtonClicked.bind(this);
this.fractionInputChanged = this.fractionInputChanged.bind(this);
this.fractionUpButtonClicked = this.fractionUpButtonClicked.bind(this);
this.fractionDownButtonClicked = this.fractionDownButtonClicked.bind(this);
this.wholeInputKeyDown = this.wholeInputKeyDown.bind(this);
this.fractionInputKeyDown = this.fractionInputKeyDown.bind(this);
this.doZeroPadFraction = this.doZeroPadFraction.bind(this);
this.init();
this.controlListeners(true);
}
controlListeners(enabled) {
if(enabled) {
this.wholeInput.addEventListener('change', this.wholeInputChanged);
this.wholeInput.addEventListener('keydown', this.wholeInputKeyDown);
this.wholeUpButton.addEventListener('click', this.wholeUpButtonClicked);
this.wholeDownButton.addEventListener('click', this.wholeDownButtonClicked);
if(this.fractionInput) this.fractionInput.addEventListener('change', this.fractionInputChanged);
if(this.fractionInput) this.fractionInput.addEventListener('keydown', this.fractionInputKeyDown);
if(this.fractionInput) this.fractionUpButton.addEventListener('click', this.fractionUpButtonClicked);
if(this.fractionInput) this.fractionDownButton.addEventListener('click', this.fractionDownButtonClicked)
} else {
this.wholeInput.removeEventListener('change', this.wholeInputChanged);
this.wholeInput.addEventListener('keydown', this.wholeInputKeyDown);
this.wholeUpButton.removeEventListener('click', this.wholeUpButtonClicked);
this.wholeDownButton.removeEventListener('click', this.wholeDownButtonClicked);
if(this.fractionInput) this.fractionInput.removeEventListener('change', this.fractionInputChanged);
if(this.fractionInput) this.fractionInput.addEventListener('keydown', this.fractionInputKeyDown);
if(this.fractionInput) this.fractionUpButton.removeEventListener('click', this.fractionUpButtonClicked);
if(this.fractionInput) this.fractionDownButton.removeEventListener('click', this.fractionDownButtonClicked)
}
}
/**
* @param {KeyboardEvent} Event
*/
wholeInputKeyDown(Event)
{
if(Event.key === 'ArrowDown') this.wholeDownButtonClicked(Event);
else if(Event.key === 'ArrowUp') this.wholeUpButtonClicked(Event);
}
/**
* @param {KeyboardEvent} Event
*/
fractionInputKeyDown(Event)
{
if(Event.key === 'ArrowDown') this.fractionDownButtonClicked(Event);
else if(Event.key === 'ArrowUp') this.fractionUpButtonClicked(Event);
}
/**
* @param {Event} Event
*/
wholeInputChanged(Event) {
this.onlyAllowEventWhenNumericKey(Event);
this.mustBeBetween(this.wholeInput, this.wholeMin, this.wholeMax);
this.processInput();
}
/**
* @param {MouseEvent} event
*/
wholeUpButtonClicked(event) {
let current = parseInt(this.wholeInput.value ? this.wholeInput.value : 0);
if(this.wholeMax && current + this.wholeStep > this.wholeMax) return;
this.wholeInput.value = current + this.wholeStep;
this.wholeInputChanged(event);
}
/**
* @param {MouseEvent} event
*/
wholeDownButtonClicked(event) {
let current = parseInt(this.wholeInput.value ? this.wholeInput.value : 0);
if(current - this.wholeStep < this.wholeMin) return;
this.wholeInput.value = current - this.wholeStep;
this.wholeInputChanged(event);
}
/**
* @param {Event} Event
*/
fractionInputChanged(Event) {
console.log('fraction changed');
this.onlyAllowEventWhenNumericKey(Event);
this.onlyAllowMaxLength(Event, this.fractionLength);
this.mustBeBetween(this.fractionInput, this.fractionMin, this.fractionMax);
if(this.zeroPadFraction) this.doZeroPadFraction();
this.processInput();
}
/**
* Prepends zeros to the fraction till it matches the fraction length
*/
doZeroPadFraction()
{
while(this.fractionInput.value.length < this.fractionLength)
this.fractionInput.value = '0'+this.fractionInput.value;
}
/**
* @param {MouseEvent} event
*/
fractionUpButtonClicked(event) {
let current = parseInt(this.fractionInput.value ? this.fractionInput.value : 0);
let newResult = current + this.fractionStep;
if(this.fractionMax && newResult > this.fractionMax) return;
if(newResult.toString().length > this.fractionLength) return;
this.fractionInput.value = newResult;
this.fractionInputChanged(event);
}
/**
* @param {MouseEvent} event
*/
fractionDownButtonClicked(event) {
let current = parseInt(this.fractionInput.value ? this.fractionInput.value : 0);
let newResult = current - this.fractionStep;
if(newResult < this.fractionMin) return;
this.fractionInput.value = newResult;
this.fractionInputChanged(event);
}
init() {
let fraction = '';
let whole = '';
//Dissect the realinput value into the whole and fraction.
if(this.realInput.value.length > this.fractionLength) fraction = this.realInput.value.slice(-this.fractionLength);
whole = this.realInput.value.substring(0, this.realInput.value.length - this.fractionLength);
//Set the whole and fraction inputs with the dissected values
this.wholeInput.value = parseInt(whole, 10);
if(this.fractionInput) this.fractionInput.value = parseInt(fraction, 10);
// Force the inputs to be between the min and max values
this.mustBeBetween(this.wholeInput, this.wholeMin, this.wholeMax);
if(this.fractionInput) this.mustBeBetween(this.fractionInput, this.fractionMin, this.fractionMax);
if(this.zeroPadFraction) this.doZeroPadFraction();
}
/**
*
* @param {Event} event
* @param {int} maxLength
*/
onlyAllowMaxLength(event, maxLength)
{
if(this.eventCausedByAllowedModifier(event)) return;
if(event.target.value.length >= maxLength) {
if(event.cancelable) event.preventDefault();
}
}
/**
* @param {Event} event
*/
onlyAllowEventWhenNumericKey(event)
{
if(!event.key) return;
if(!this.isNumber(event.key) && !this.eventCausedByAllowedModifier(event)) {
if(event.cancelable) event.preventDefault();
}
}
/**
* @param {Event} event
*/
eventCausedByAllowedModifier(event)
{
if(!event.key) return;
return event.key.toLowerCase() === 'backspace' || event.key.toLowerCase() === 'delete' || event.key.toLowerCase() === 'arrowleft' || event.key.toLowerCase() === 'arrowright';
}
/**
* Save the rendered values to the real input so it can be saved.
*/
processInput()
{
this.realInput.value = this.wholeInput.value;
if(this.fractionLength > 0) {
this.realInput.value += this.padEnd(this.fractionInput.value, this.fractionLength, '0');
}
}
/**
* @param {HTMLInputElement} inputElement
* @param {int} min
* @param {int} max
*/
mustBeBetween(inputElement, min, max) {
let number = parseInt(inputElement.value, 10);
if(number) {
if((min || min === 0) && number < min) inputElement.value = min;
if(max && number > max) inputElement.value = max;
} else if(isNaN(number)) {
inputElement.value = (0).toString();
}
}
/**
* @param number
* @return {boolean}
*/
isNumber(number) {
return !isNaN(parseFloat(number)) && isFinite(number);
}
/**
* @param targetLength
* @param input
* @param padString
* @return {string}
*/
padEnd(input, targetLength, padString) {
targetLength = Math.floor(targetLength) || 0;
if(targetLength < input.length) return String(input);
padString = padString ? String(padString) : " ";
let pad = "";
let len = targetLength - input.length;
let i = 0;
while(pad.length < len) {
if(!padString[i]) {
i = 0;
}
pad += padString[i];
i++;
}
return String(input).slice(0) + pad;
};
}