<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge, chrome=1">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi, minimal-ui">
<style>
[data-product-id] {
display: block;
transform: translate(calc(50vw - 50%), calc(50vh - 50%));
margin: .7em;
border: 0;
}
[data-product-id]:not([type=range]) {
box-shadow: 0 0 1.25vmin gray inset;
padding: .5em;
}
[data-product-id]:invalid {
background: #f88;
}
</style>
</head>
<body>
<!-- Используйте подходящие элементы, здесь вводится число, поэтому я использую input[type=number] -->
<input type="number" min="0" max="50" value="1" data-product-id="2" pattern="\d|[1-4]\d|50">
<input type="number" min="0" max="50" value="1" data-product-id="3" pattern="\d|[1-4]\d|50">
<!-- Для диапазонов также подойдёт input[type=range] -->
<input type="range" min="0" max="50" value="1" data-product-id="1">
<input type="range" min="0" max="50" value="1" data-product-id="0">
<script>
document.addEventListener("input", function(event) {
if(!event.target.hasAttribute("data-product-id")) return;
event.preventDefault();
var input = event.target;
// "Втискиваем" число в заданный диапазон если вне
var value = input.value;
value = isFinite(value) ? value : input.min; // сбросим в минимум, если не число
value = Math.max(input.min, Math.min(input.value, input.max));
// Заменяем на "втиснутое", если отличается от исходного
if(value != input.value)
input.value = value;
// Число value готово
// Вы можете здесь вызвать свою функцию с этим числом,
// я для примера закрашу {{значение}}% от ширины окна
var color = ["black", "purple", "teal", "orange"][input.getAttribute("data-product-id")];
document.body.style.background = "linear-gradient(90deg, " + color + " " + value + "%, transparent 0)";
});
</script>
</body>
</html>