Slider Decimal Support Fix
May 15, 2025 · AI Conversations
<style>
.price-input {
width: 100%;
display: flex;
margin: 30px 0 35px;
}
.price-input .field {
display: flex;
width: 100%;
height: 45px;
align-items: center;
}
.field input {
width: 100%;
height: 100%;
outline: none;
font-size: 19px;
margin-left: 12px;
border-radius: 5px;
text-align: center;
border: 1px solid #999;
-moz-appearance: textfield;
}
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
}
.price-input .separator {
width: 130px;
display: flex;
font-size: 19px;
align-items: center;
justify-content: center;
}
.slider {
height: 5px;
position: relative;
background: #ddd;
border-radius: 5px;
}
.slider .progress {
height: 100%;
left: 25%;
right: 25%;
position: absolute;
border-radius: 5px;
background: #17a2b8;
}
.range-input {
position: relative;
}
.range-input input {
position: absolute;
width: 100%;
height: 5px;
top: -5px;
background: none;
pointer-events: none;
-webkit-appearance: none;
-moz-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
height: 17px;
width: 17px;
border-radius: 50%;
background: #17a2b8;
pointer-events: auto;
-webkit-appearance: none;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.05);
}
input[type="range"]::-moz-range-thumb {
height: 17px;
width: 17px;
border: none;
border-radius: 50%;
background: #17a2b8;
pointer-events: auto;
-moz-appearance: none;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.05);
}
/* Support */
.support-box {
top: 2rem;
position: relative;
bottom: 0;
text-align: center;
display: block;
}
.b-btn {
color: white;
text-decoration: none;
font-weight: bold;
}
.b-btn.paypal i {
color: blue;
}
.b-btn:hover {
text-decoration: none;
font-weight: bold;
}
.b-btn i {
font-size: 20px;
color: yellow;
margin-top: 2rem;
}
</style>
<script>
const rangeInput = document.querySelectorAll(".range-input input"),
priceInput = document.querySelectorAll(".price-input input"),
range = document.querySelector(".slider .progress");
let priceGap = 1000;
priceInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minPrice = parseInt(priceInput[0].value),
maxPrice = parseInt(priceInput[1].value);
if (maxPrice - minPrice >= priceGap && maxPrice <= rangeInput[1].max) {
if (e.target.className === "input-min") {
rangeInput[0].value = minPrice;
range.style.left = (minPrice / rangeInput[0].max) * 100 + "%";
} else {
rangeInput[1].value = maxPrice;
range.style.right = 100 - (maxPrice / rangeInput[1].max) * 100 + "%";
}
}
});
});
rangeInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minVal = parseInt(rangeInput[0].value),
maxVal = parseInt(rangeInput[1].value);
if (maxVal - minVal < priceGap) {
if (e.target.className === "range-min") {
rangeInput[0].value = maxVal - priceGap;
} else {
rangeInput[1].value = minVal + priceGap;
}
} else {
priceInput[0].value = minVal;
priceInput[1].value = maxVal;
range.style.left = (minVal / rangeInput[0].max) * 100 + "%";
range.style.right = 100 - (maxVal / rangeInput[1].max) * 100 + "%";
}
});
});
</script>
above price slider not work when I add min 25.0 and max.90.0
(minVal / rangeInput[0].max) * 100
If your values are floats, but the slider only accepts integers (`step="1"`), it causes imprecision or the range UI to behave unexpectedly.
—
### ✅ Here's how to fix it properly:
#### ✅ Step 1: Allow decimal step
Update the slider inputs to allow decimals (like `step="0.1"`):
<input type="range" class="range-min" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $minPrice ?>" step="0.1">
<input type="range" class="range-max" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $maxPrice ?>" step="0.1">
#### ✅ Step 2: Use `parseFloat()` instead of `parseInt()` in JS
Update the JS to handle decimal inputs:
let priceGap = 1.0; // or a smaller value like 0.5 for finer control
priceInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minPrice = parseFloat(priceInput[0].value),
maxPrice = parseFloat(priceInput[1].value);
if (maxPrice - minPrice >= priceGap && maxPrice <= parseFloat(rangeInput[1].max)) {
if (e.target.className === "input-min") {
rangeInput[0].value = minPrice;
range.style.left = ((minPrice - parseFloat(rangeInput[0].min)) / (parseFloat(rangeInput[0].max) - parseFloat(rangeInput[0].min))) * 100 + "%";
} else {
rangeInput[1].value = maxPrice;
range.style.right = 100 - ((maxPrice - parseFloat(rangeInput[1].min)) / (parseFloat(rangeInput[1].max) - parseFloat(rangeInput[1].min))) * 100 + "%";
}
}
});
});
rangeInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minVal = parseFloat(rangeInput[0].value),
maxVal = parseFloat(rangeInput[1].value);
if (maxVal - minVal < priceGap) {
if (e.target.className === "range-min") {
rangeInput[0].value = maxVal - priceGap;
} else {
rangeInput[1].value = minVal + priceGap;
}
} else {
priceInput[0].value = minVal.toFixed(1);
priceInput[1].value = maxVal.toFixed(1);
range.style.left = ((minVal - parseFloat(rangeInput[0].min)) / (parseFloat(rangeInput[0].max) - parseFloat(rangeInput[0].min))) * 100 + "%";
range.style.right = 100 - ((maxVal - parseFloat(rangeInput[1].min)) / (parseFloat(rangeInput[1].max) - parseFloat(rangeInput[1].min))) * 100 + "%";
}
});
});
—
### ✅ Bonus Tips
– If your product prices are always whole numbers, you can skip the decimals and set `step="1"` and use `parseInt()`.
– If prices have decimals (like `25.5`, `99.9`), use `step="0.1"` and `parseFloat()` as shown.
—
Let me know if you want to display currency symbols (like € or ₹) or round values to whole numbers visually only.
You're using **floating-point numbers** for prices like `25.0` and `90.0`, but your slider is acting weird because:
1. The JavaScript uses `parseInt()` (which truncates floats).
2. CSS progress bar (`left/right`) percentages don’t update correctly for decimal values.
3. The HTML may not correctly bind min/max values if decimals are passed without enforcing `step`.
—
### ✅ FULL FIX (WORKING CODE BELOW)
We'll do 3 things:
– Use `step="0.1"` in sliders.
– Use `parseFloat()` instead of `parseInt()` in JavaScript.
– Make sure values like `25.0` render visually correctly.
—
### ✅ 1. Update Slider HTML
Change:
<input type="range" class="range-min" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $minPrice ?>" step="0.1">
<input type="range" class="range-max" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $maxPrice ?>" step="0.1">
Make sure `$minPrice` and `$maxPrice` are floats like `25.0`, `90.0`.
—
### ✅ 2. Update JavaScript (copy-paste below)
<script>
const rangeInput = document.querySelectorAll(".range-input input"),
priceInput = document.querySelectorAll(".price-input input"),
range = document.querySelector(".slider .progress");
let priceGap = 1.0;
priceInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minPrice = parseFloat(priceInput[0].value),
maxPrice = parseFloat(priceInput[1].value),
minLimit = parseFloat(rangeInput[0].min),
maxLimit = parseFloat(rangeInput[1].max);
if (maxPrice - minPrice >= priceGap && maxPrice <= maxLimit && minPrice >= minLimit) {
if (e.target.classList.contains("input-min")) {
rangeInput[0].value = minPrice;
range.style.left = ((minPrice - minLimit) / (maxLimit - minLimit)) * 100 + "%";
} else {
rangeInput[1].value = maxPrice;
range.style.right = 100 - ((maxPrice - minLimit) / (maxLimit - minLimit)) * 100 + "%";
}
}
});
});
rangeInput.forEach((input) => {
input.addEventListener("input", (e) => {
let minVal = parseFloat(rangeInput[0].value),
maxVal = parseFloat(rangeInput[1].value),
minLimit = parseFloat(rangeInput[0].min),
maxLimit = parseFloat(rangeInput[1].max);
if (maxVal - minVal < priceGap) {
if (e.target.classList.contains("range-min")) {
rangeInput[0].value = (maxVal - priceGap).toFixed(1);
} else {
rangeInput[1].value = (minVal + priceGap).toFixed(1);
}
} else {
priceInput[0].value = minVal.toFixed(1);
priceInput[1].value = maxVal.toFixed(1);
range.style.left = ((minVal - minLimit) / (maxLimit - minLimit)) * 100 + "%";
range.style.right = 100 - ((maxVal - minLimit) / (maxLimit - minLimit)) * 100 + "%";
}
});
});
</script>
—
### ✅ 3. Final Validation
Ensure `$minPrice` and `$maxPrice` passed from PHP are like:
$minPrice = 25.0;
$maxPrice = 90.0;
Also make sure:
<input type="text" class="input-min" value="<?= $minPrice ?>">
<input type="text" class="input-max" value="<?= $maxPrice ?>">
—
### ✅ After This
– Try dragging both ends of the slider — should now work with 25.0 to 90.0 range.
– If you're still facing issues, press F12 → Console, and let me know if any error appears.
Would you like me to test it with live dummy values in a full working HTML example?
{
$req = $this->app->make(Request::class);
$db = $this->app->make(Connection::class);
$url = $req->request->get('url');
$name = $req->request->get('name');
$settings = $req->request->get('settings');
if ($url && $name) {
$db->insert('shoppingfeedconfiguration', compact('url', 'name', 'settings'));
$this->flash('success', 'Feed created successfully.');
return Redirect::to('/dashboard/shopping_feed/');
}
}
Now save its serliaze format
Here’s your updated `submit()` method:
—
### ✅ Updated `submit()` Method with `serialize()`:
use ConcreteCoreHttpRequest;
use ConcreteCoreDatabaseConnectionConnection;
use ConcreteCoreSupportFacadeRedirect;
public function submit()
{
$req = $this->app->make(Request::class);
$db = $this->app->make(Connection::class);
$url = $req->request->get('url');
$name = $req->request->get('name');
$settings = $req->request->get('settings');
if ($url && $name) {
// Serialize settings array before saving
$serializedSettings = serialize($settings);
$db->insert('shoppingfeedconfiguration', [
'url' => $url,
'name' => $name,
'settings' => $serializedSettings
]);
$this->flash('success', 'Feed created successfully.');
return Redirect::to('/dashboard/shopping_feed/');
}
// Optional: show error if URL or name is missing
$this->flash('error', 'URL and Name are required.');
return Redirect::to('/dashboard/shopping_feed/add');
}
—
### ✅ To Retrieve Later:
When reading this back from the DB, use:
$settings = unserialize($row['settings']);
—
Let me know if you also want to store JSON instead of serialized data — it's more portable if you ever export to another system.