256 lines
7.3 KiB
JavaScript
256 lines
7.3 KiB
JavaScript
(function (window, document) {
|
|
'use strict';
|
|
|
|
var PorcentajeBox = {};
|
|
|
|
PorcentajeBox.initAll = function () {
|
|
var boxes = document.querySelectorAll('[data-porcentaje-box="true"]');
|
|
|
|
for (var i = 0; i < boxes.length; i++) {
|
|
PorcentajeBox.init(boxes[i]);
|
|
}
|
|
};
|
|
|
|
PorcentajeBox.init = function (root) {
|
|
if (!root || root.getAttribute('data-porcentaje-init') === 'true')
|
|
return;
|
|
|
|
root.setAttribute('data-porcentaje-init', 'true');
|
|
|
|
var input = root.querySelector('[data-porcentaje-input="true"]');
|
|
var minus = root.querySelector('[data-porcentaje-minus="true"]');
|
|
var plus = root.querySelector('[data-porcentaje-plus="true"]');
|
|
var bar = root.querySelector('[data-porcentaje-bar="true"]') || root.querySelector('.porcentaje-box-bar');
|
|
|
|
var holdTimer = null;
|
|
var dragging = false;
|
|
|
|
function stopActions() {
|
|
dragging = false;
|
|
|
|
if (holdTimer) {
|
|
clearInterval(holdTimer);
|
|
holdTimer = null;
|
|
}
|
|
}
|
|
|
|
function preventButton(e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
return false;
|
|
}
|
|
|
|
function startButtonHold(e, direction) {
|
|
preventButton(e);
|
|
stopActions();
|
|
|
|
PorcentajeBox.change(root, direction);
|
|
|
|
holdTimer = setInterval(function () {
|
|
PorcentajeBox.change(root, direction);
|
|
}, 160);
|
|
}
|
|
|
|
function setFromMouse(e) {
|
|
if (!bar)
|
|
return;
|
|
|
|
var rect = bar.getBoundingClientRect();
|
|
|
|
if (!rect.width)
|
|
return;
|
|
|
|
var percent = ((e.clientX - rect.left) / rect.width) * 100;
|
|
|
|
PorcentajeBox.setValue(root, Math.round(percent), false);
|
|
}
|
|
|
|
if (minus) {
|
|
minus.addEventListener('pointerdown', function (e) {
|
|
startButtonHold(e, -1);
|
|
});
|
|
|
|
minus.addEventListener('click', preventButton);
|
|
minus.addEventListener('mousedown', preventButton);
|
|
minus.addEventListener('mouseup', stopActions);
|
|
minus.addEventListener('mouseleave', stopActions);
|
|
}
|
|
|
|
if (plus) {
|
|
plus.addEventListener('pointerdown', function (e) {
|
|
startButtonHold(e, 1);
|
|
});
|
|
|
|
plus.addEventListener('click', preventButton);
|
|
plus.addEventListener('mousedown', preventButton);
|
|
plus.addEventListener('mouseup', stopActions);
|
|
plus.addEventListener('mouseleave', stopActions);
|
|
}
|
|
|
|
if (input) {
|
|
input.addEventListener('input', function () {
|
|
var value = input.value;
|
|
|
|
if (value === '' || value === '.' || value === ',') {
|
|
PorcentajeBox.paint(root, 0);
|
|
return;
|
|
}
|
|
|
|
value = PorcentajeBox.getFloat(value, 0);
|
|
|
|
var min = PorcentajeBox.getFloat(root.getAttribute('data-min'), 0);
|
|
var max = PorcentajeBox.getFloat(root.getAttribute('data-max'), 100);
|
|
|
|
if (value < min)
|
|
value = min;
|
|
|
|
if (value > max)
|
|
value = max;
|
|
|
|
var hidden = root.querySelector('input[type="hidden"]');
|
|
|
|
if (hidden)
|
|
hidden.value = value;
|
|
|
|
PorcentajeBox.paint(root, value);
|
|
});
|
|
|
|
input.addEventListener('blur', function () {
|
|
PorcentajeBox.setValue(root, input.value, false);
|
|
});
|
|
|
|
input.addEventListener('keydown', function (e) {
|
|
if (e.key === 'ArrowUp') {
|
|
e.preventDefault();
|
|
PorcentajeBox.change(root, 1);
|
|
}
|
|
|
|
if (e.key === 'ArrowDown') {
|
|
e.preventDefault();
|
|
PorcentajeBox.change(root, -1);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (bar) {
|
|
bar.addEventListener('pointerdown', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
|
|
dragging = true;
|
|
setFromMouse(e);
|
|
});
|
|
|
|
document.addEventListener('pointermove', function (e) {
|
|
if (!dragging)
|
|
return;
|
|
|
|
setFromMouse(e);
|
|
});
|
|
}
|
|
|
|
document.addEventListener('pointerup', stopActions);
|
|
document.addEventListener('mouseup', stopActions);
|
|
document.addEventListener('mouseleave', stopActions);
|
|
|
|
PorcentajeBox.refresh(root);
|
|
};
|
|
|
|
PorcentajeBox.change = function (root, direction) {
|
|
var current = PorcentajeBox.getValue(root);
|
|
var step = PorcentajeBox.getFloat(root.getAttribute('data-step'), 1);
|
|
|
|
PorcentajeBox.setValue(root, current + (step * direction), false);
|
|
};
|
|
|
|
PorcentajeBox.setValue = function (root, value, roundStep) {
|
|
var min = PorcentajeBox.getFloat(root.getAttribute('data-min'), 0);
|
|
var max = PorcentajeBox.getFloat(root.getAttribute('data-max'), 100);
|
|
var step = PorcentajeBox.getFloat(root.getAttribute('data-step'), 1);
|
|
|
|
value = PorcentajeBox.getFloat(value, min);
|
|
|
|
if (roundStep === true)
|
|
value = PorcentajeBox.roundToStep(value, step);
|
|
|
|
if (value < min)
|
|
value = min;
|
|
|
|
if (value > max)
|
|
value = max;
|
|
|
|
value = PorcentajeBox.cleanDecimal(value);
|
|
|
|
var hidden = root.querySelector('input[type="hidden"]');
|
|
var input = root.querySelector('[data-porcentaje-input="true"]');
|
|
|
|
if (hidden)
|
|
hidden.value = value;
|
|
|
|
if (input)
|
|
input.value = value;
|
|
|
|
PorcentajeBox.paint(root, value);
|
|
};
|
|
|
|
PorcentajeBox.getValue = function (root) {
|
|
var hidden = root.querySelector('input[type="hidden"]');
|
|
|
|
if (!hidden)
|
|
return 0;
|
|
|
|
return PorcentajeBox.getFloat(hidden.value, 0);
|
|
};
|
|
|
|
PorcentajeBox.refresh = function (root) {
|
|
PorcentajeBox.setValue(root, PorcentajeBox.getValue(root), false);
|
|
};
|
|
|
|
PorcentajeBox.paint = function (root, value) {
|
|
var fill = root.querySelector('[data-porcentaje-fill="true"]');
|
|
var dot = root.querySelector('[data-porcentaje-dot="true"]');
|
|
var text = root.querySelector('[data-porcentaje-text="true"]');
|
|
|
|
value = PorcentajeBox.getFloat(value, 0);
|
|
|
|
if (value < 0)
|
|
value = 0;
|
|
|
|
if (value > 100)
|
|
value = 100;
|
|
|
|
if (fill)
|
|
fill.style.width = value + '%';
|
|
|
|
if (dot)
|
|
dot.style.left = value + '%';
|
|
|
|
if (text)
|
|
text.innerHTML = 'Completado: ' + value + '%';
|
|
};
|
|
|
|
PorcentajeBox.getFloat = function (value, defaultValue) {
|
|
if (value === null || value === undefined)
|
|
return defaultValue;
|
|
|
|
value = String(value).replace(',', '.');
|
|
|
|
var number = parseFloat(value);
|
|
|
|
return isNaN(number) ? defaultValue : number;
|
|
};
|
|
|
|
PorcentajeBox.roundToStep = function (value, step) {
|
|
if (!step || step <= 0)
|
|
return value;
|
|
|
|
return Math.round(value / step) * step;
|
|
};
|
|
|
|
PorcentajeBox.cleanDecimal = function (value) {
|
|
return parseFloat(value.toFixed(4));
|
|
};
|
|
|
|
window.PorcentajeBox = PorcentajeBox;
|
|
|
|
})(window, document); |