Files
Jorge Luis caudillo esparza 6685ef63fb Initial commit
2026-07-14 11:15:57 -07:00

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);