Slider Decimal Support Fix

User
Add New Feed URL

<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

Assistant
The issue you're facing is due to using **floating-point values (like 25.0 and 90.0)** in a slider (“) that expects **integers** by default — especially when doing math operations like:

(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.

User
still not work
Assistant
Thanks — let’s now **fix this completely**, step by step.

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?

User
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) {
$db->insert('shoppingfeedconfiguration', compact('url', 'name', 'settings'));
$this->flash('success', 'Feed created successfully.');
return Redirect::to('/dashboard/shopping_feed/');
}
}
Now save its serliaze format

Assistant
To store the `settings` array in serialized format when saving to the database, you can use PHP's `serialize()` function before inserting.

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.

Leave a Comment

Your email address will not be published. Required fields are marked *