Community Store Category Issue

User
community_store concrete cms product category add option not showing
"No pages have been used to categorise products"
Assistant
The error message:

> **"No pages have been used to categorise products"**

in **Community Store for Concrete CMS** typically means that no product categories have been set up using **Concrete pages**, which Community Store uses to organize products (each category is a **Page** under a designated "Product Parent Page").

### ✅ Here's how to fix it:

### **Step 1: Create a Category Page Structure**

1. Go to your **Sitemap** (`/dashboard/sitemap/full`).
2. Find or create a parent page like:
– `/products`
– `/shop`
– or `/store`

3. Under that parent, **add subpages** for each category (e.g., “Tiles”, “Accessories”).
– Use the **Page Type**: `store_product_list` (or similar depending on your theme/setup).
– These subpages will be used as categories.

### **Step 2: Assign the Category Page Path in Settings**

1. Go to **Dashboard > Store > Settings**.
2. Under **Product List Page**, select the **parent page** you created (`/products`, etc.).
– This tells Community Store where to look for category subpages.
3. Save settings.

### **Step 3: Verify Page Type of Subpages**

Ensure that your category pages are:
– Not of type “External Link”
– Not system pages
– Have proper permissions

If unsure:
1. Go to **each category page** in sitemap.
2. Click **Edit Page**, then **Page Settings**.
3. Confirm page type is a standard or `store_product_list`.

### ✅ After this:

When editing a **product**, you should now see those category pages listed under the "Product Category" dropdown or multiselect in the product form.

Let me know if you want to auto-create some category pages via a script or dashboard page.

User
we have product table get min / max price
Assistant
To get the **minimum and maximum product prices** from the Community Store's `CommunityStoreProduct` table in Concrete CMS, you can use a simple query.

Assuming you're using the default `CommunityStoreProduct` entity or table, here's how you can fetch the min and max prices.

### ✅ **Method 1: Direct SQL Query via DB**

“`php
use Core

User
CommunityStoreProducts
col-pPrice
then add product range slider in add.php bootstrap
Assistant
Perfect — here's how to do **both**:

## ✅ 1. **Get Min and Max from `CommunityStoreProducts.pPrice`**

use Database;

$db = Database::connection();
$row = $db->fetchAssociative("SELECT MIN(pPrice) AS min_price, MAX(pPrice) AS max_price FROM CommunityStoreProducts");

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 0;

You can now use `$minPrice` and `$maxPrice` to set up a range slider.

## ✅ 2. **Add Range Slider in `add.php` using Bootstrap**

<div class="form-group">
  <label for="priceRange">Price Range</label>
  <div>
    <input type="range" class="form-range" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" id="priceRange" name="settings[price_range]" step="1" 
      oninput="document.getElementById('priceRangeValue').innerText = this.value">
    <small>Selected: <span id="priceRangeValue"><?= $minPrice ?></span></small>
  </div>
</div>

### 🔁 To preserve value when editing:
If you're passing `settings['price_range']`:

$value = $settings['price_range'] ?? $minPrice;

Then update the slider like:

<input type="range" class="form-range" min="<?= $minPrice ?>" max="<?= $maxPrice ?>" 
  id="priceRange" name="settings[price_range]" value="<?= $value ?>" 
  oninput="document.getElementById('priceRangeValue').innerText = this.value">
<small>Selected: <span id="priceRangeValue"><?= $value ?></span></small>

Let me know if you'd like to allow **both min and max range selection** (dual-range slider) instead of a single-value slider.

User
also dislay min and max price
Assistant
To display the **Min and Max price values** alongside the slider in `add.php`, here's a clean Bootstrap-integrated setup:

### ✅ Full Code for Single Range Slider with Min & Max Display

<?php
use Database;

$db = Database::connection();
$row = $db->fetchAssociative("SELECT MIN(pPrice) AS min_price, MAX(pPrice) AS max_price FROM CommunityStoreProducts");

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 0;

$value = $settings['price_range'] ?? $minPrice;
?>

<div class="form-group">
  <label for="priceRange">Select Price</label>
  <div class="d-flex justify-content-between mb-1">
    <span>Min: ₹<?= number_format($minPrice, 2) ?></span>
    <span>Max: ₹<?= number_format($maxPrice, 2) ?></span>
  </div>

  <input type="range" class="form-range" id="priceRange" name="settings[price_range]"
    min="<?= $minPrice ?>" max="<?= $maxPrice ?>" step="1" value="<?= $value ?>"
    oninput="document.getElementById('priceRangeValue').innerText = this.value">

  <small>Selected Price: ₹<span id="priceRangeValue"><?= $value ?></span></small>
</div>

### 🧪 Output Example

– Min: ₹100
– Max: ₹1000
– Slider with selected value: ₹300

Let me know if you want a **dual-range slider** (for both min & max inputs), or to **save both min and max price range settings**.

User
where cummnity store currency stored in db table
Assistant
In **Community Store for Concrete CMS**, the **currency** setting is stored in the `Config` table, **not in a dedicated store table**.

### ✅ Location of Currency Setting:

– **Table**: `Config`
– **Key**: `community_store.currency`

### 🧾 Example SQL to Get Currency:

SELECT value FROM Config WHERE configNamespace = 'community_store' AND configKey = 'currency';

Or in PHP:

use ConcreteCoreSupportFacadeConfig;

$currency = Config::get('community_store.currency'); // e.g., "USD", "EUR", "INR"

### 🪙 Related Currency Display Settings:

You might also want:
– `community_store.currency_symbol`
– `community_store.currency_symbol_position` (e.g., "before", "after")

These are also stored in the `Config` table.

$symbol = Config::get('community_store.currency_symbol');
$position = Config::get('community_store.currency_symbol_position'); // before or after

Let me know if you want to display prices with symbol formatting based on those settings.

User
in price range slider also slide form max side
and in db save both min and max based on the slider
Assistant
Great — you want a **dual-thumb range slider** for selecting both **min and max price**, and then store both in the DB.

### ✅ 1. **Store both Min and Max in DB**

You can save in `settings['min_price']` and `settings['max_price']` when saving the form:

$minSelected = $this->post('settings')['min_price'];
$maxSelected = $this->post('settings')['max_price'];

Store them as JSON or in separate DB columns, depending on your setup.

### ✅ 2. **HTML & JS for Dual Range Slider in `add.php` (Bootstrap Compatible)**

<?php
use Database;

$db = Database::connection();
$row = $db->fetchAssociative("SELECT MIN(pPrice) AS min_price, MAX(pPrice) AS max_price FROM CommunityStoreProducts");

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 1000;

$selectedMin = $settings['min_price'] ?? $minPrice;
$selectedMax = $settings['max_price'] ?? $maxPrice;
?>

<div class="form-group">
  <label>Price Range</label>
  <div class="d-flex justify-content-between mb-1">
    <span>Min: ₹<?= number_format($minPrice, 2) ?></span>
    <span>Max: ₹<?= number_format($maxPrice, 2) ?></span>
  </div>

  <div class="position-relative" style="height: 40px;">
    <input type="range" name="settings[min_price]" class="form-range position-absolute w-100"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" step="1"
      value="<?= $selectedMin ?>" id="minRange"
      oninput="updateSliderValues()">

    <input type="range" name="settings[max_price]" class="form-range position-absolute w-100"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" step="1"
      value="<?= $selectedMax ?>" id="maxRange"
      oninput="updateSliderValues()">
  </div>

  <div class="mt-2">
    <small>Selected Range: ₹<span id="minValue"><?= $selectedMin ?></span> – ₹<span id="maxValue"><?= $selectedMax ?></span></small>
  </div>
</div>

<script>
  function updateSliderValues() {
    const minSlider = document.getElementById('minRange');
    const maxSlider = document.getElementById('maxRange');

    let min = parseInt(minSlider.value);
    let max = parseInt(maxSlider.value);

    if (min > max) {
      // swap values to prevent cross-over
      [min, max] = [max, min];
      minSlider.value = min;
      maxSlider.value = max;
    }

    document.getElementById('minValue').innerText = min;
    document.getElementById('maxValue').innerText = max;
  }

  document.addEventListener('DOMContentLoaded', updateSliderValues);
</script>

### ✅ 3. **On Save (Controller Logic)**

$minSelected = $this->post('settings')['min_price'] ?? 0;
$maxSelected = $this->post('settings')['max_price'] ?? 0;

$db->insert('shoppingfeedconfiguration', [
    'url' => $url,
    'name' => $name,
    'settings' => json_encode([
        'min_price' => $minSelected,
        'max_price' => $maxSelected
    ])
]);

You can also store them in two separate columns if needed.

Let me know if you want a prettier UI (like jQuery UI slider or noUiSlider), or price formatting with currency symbol too.

User
two slider dots not showing
Assistant
If you're seeing only **one slider dot**, it’s likely because:

– Two `input type="range"` sliders are stacked **exactly on top of each other**.
– Without custom styling, one overlaps the other, so only the topmost one (e.g. `maxRange`) is visible/interactable.

### ✅ Fix: Style them so both thumbs are visible

Here’s a **working and styled solution** to make both range thumbs visible:

### ✅ Updated Dual Range Slider Code (Pure HTML + CSS + JS):

<?php
use Database;

$db = Database::connection();
$row = $db->fetchAssociative("SELECT MIN(pPrice) AS min_price, MAX(pPrice) AS max_price FROM CommunityStoreProducts");

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 1000;

$selectedMin = $settings['min_price'] ?? $minPrice;
$selectedMax = $settings['max_price'] ?? $maxPrice;
?>

<style>
.range-container {
  position: relative;
  width: 100%;
  height: 50px;
}
.range-container input[type=range] {
  position: absolute;
  width: 100%;
  pointer-events: none; /* disable default drag */
  -webkit-appearance: none;
  background: transparent;
}
.range-container input[type=range]::-webkit-slider-thumb {
  pointer-events: all;
  width: 20px;
  height: 20px;
  background: #007bff;
  border-radius: 50%;
  border: none;
  -webkit-appearance: none;
}
.range-container input[type=range]::-moz-range-thumb {
  pointer-events: all;
  width: 20px;
  height: 20px;
  background: #007bff;
  border-radius: 50%;
  border: none;
}
</style>

<div class="form-group">
  <label>Price Range</label>
  <div class="d-flex justify-content-between mb-1">
    <span>Min: ₹<?= number_format($minPrice, 2) ?></span>
    <span>Max: ₹<?= number_format($maxPrice, 2) ?></span>
  </div>

  <div class="range-container">
    <input type="range" id="minRange" name="settings[min_price]"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $selectedMin ?>" step="1"
      oninput="handleRangeSlide()">
    <input type="range" id="maxRange" name="settings[max_price]"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $selectedMax ?>" step="1"
      oninput="handleRangeSlide()">
  </div>

  <div class="mt-2">
    <small>Selected: ₹<span id="minValue"><?= $selectedMin ?></span> – ₹<span id="maxValue"><?= $selectedMax ?></span></small>
  </div>
</div>

<script>
function handleRangeSlide() {
  const minSlider = document.getElementById('minRange');
  const maxSlider = document.getElementById('maxRange');
  let minVal = parseInt(minSlider.value);
  let maxVal = parseInt(maxSlider.value);

  if (minVal > maxVal) {
    [minVal, maxVal] = [maxVal, minVal];
    minSlider.value = minVal;
    maxSlider.value = maxVal;
  }

  document.getElementById('minValue').textContent = minVal;
  document.getElementById('maxValue').textContent = maxVal;
}

document.addEventListener('DOMContentLoaded', handleRangeSlide);
</script>

### ✅ Notes:

– **`pointer-events: none`** disables default interaction on the range bar.
– **Thumbs are restyled** and **pointer-events re-enabled** on them, so both can be dragged.
– This solution works without any external library.

Let me know if you want a **more interactive visual bar fill** (e.g., colored progress between the thumbs).

User
okay now grey line not showing
Assistant
Great — if the **gray line (track) between slider thumbs** is not showing, it's because:

> You're using two overlapping “ elements, and by default each range slider renders its own track, but they overlap and don't "merge" into one visual track.

### ✅ Solution: Add a **custom background track** that visually fills between the min and max sliders.

We’ll create a fake "track fill" using a `div` positioned underneath the thumbs, then dynamically set its left and width based on the slider values.

### ✅ Full Working Code with Track Fill (Grey Line)

<?php
use Database;

$db = Database::connection();
$row = $db->fetchAssociative("SELECT MIN(pPrice) AS min_price, MAX(pPrice) AS max_price FROM CommunityStoreProducts");

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 1000;

$selectedMin = $settings['min_price'] ?? $minPrice;
$selectedMax = $settings['max_price'] ?? $maxPrice;
$range = $maxPrice - $minPrice;
?>

<style>
.range-container {
  position: relative;
  width: 100%;
  height: 50px;
}
.range-track {
  position: absolute;
  height: 6px;
  background: #ccc;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  border-radius: 3px;
  z-index: 1;
}
.range-fill {
  position: absolute;
  height: 6px;
  background: #007bff;
  top: 50%;
  transform: translateY(-50%);
  border-radius: 3px;
  z-index: 2;
}
.range-container input[type=range] {
  position: absolute;
  width: 100%;
  pointer-events: none;
  -webkit-appearance: none;
  background: transparent;
  z-index: 3;
}
.range-container input[type=range]::-webkit-slider-thumb {
  pointer-events: all;
  width: 20px;
  height: 20px;
  background: #007bff;
  border-radius: 50%;
  border: none;
  -webkit-appearance: none;
}
.range-container input[type=range]::-moz-range-thumb {
  pointer-events: all;
  width: 20px;
  height: 20px;
  background: #007bff;
  border-radius: 50%;
  border: none;
}
</style>

<div class="form-group">
  <label>Price Range</label>
  <div class="d-flex justify-content-between mb-1">
    <span>Min: ₹<?= number_format($minPrice, 2) ?></span>
    <span>Max: ₹<?= number_format($maxPrice, 2) ?></span>
  </div>

  <div class="range-container">
    <div class="range-track"></div>
    <div class="range-fill" id="rangeFill"></div>

    <input type="range" id="minRange" name="settings[min_price]"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $selectedMin ?>" step="1"
      oninput="handleRangeSlide()">
    <input type="range" id="maxRange" name="settings[max_price]"
      min="<?= $minPrice ?>" max="<?= $maxPrice ?>" value="<?= $selectedMax ?>" step="1"
      oninput="handleRangeSlide()">
  </div>

  <div class="mt-2">
    <small>Selected: ₹<span id="minValue"><?= $selectedMin ?></span> – ₹<span id="maxValue"><?= $selectedMax ?></span></small>
  </div>
</div>

<script>
function handleRangeSlide() {
  const minSlider = document.getElementById('minRange');
  const maxSlider = document.getElementById('maxRange');
  const min = parseInt(minSlider.value);
  const max = parseInt(maxSlider.value);
  const fill = document.getElementById('rangeFill');

  const minValue = Math.min(min, max);
  const maxValue = Math.max(min, max);

  const total = <?= $range ?>;
  const minPercent = ((minValue - <?= $minPrice ?>) / total) * 100;
  const maxPercent = ((maxValue - <?= $minPrice ?>) / total) * 100;

  fill.style.left = minPercent + "%";
  fill.style.width = (maxPercent - minPercent) + "%";

  document.getElementById('minValue').textContent = minValue;
  document.getElementById('maxValue').textContent = maxValue;
}

document.addEventListener('DOMContentLoaded', handleRangeSlide);
</script>

### ✅ What This Does:
– Adds a `range-track` (gray line behind sliders)
– Adds a `range-fill` (blue line between thumbs)
– Dynamically adjusts its position/width based on current slider values

Let me know if you want to add:
– Tooltips above thumbs
– Touch/mobile support improvements
– jQuery/nouislider version with drag-combined behavior

User
okay now show slider on one at min price and other at max price
Assistant
✅ Got it — you want:

– **Left slider thumb** (Min) to be locked to the **minimum price**.
– **Right slider thumb** (Max) to be locked to the **maximum price**.

In other words:
– **Min slider default position** → at `minPrice`
– **Max slider default position** → at `maxPrice`

### ✅ Code Update

In the PHP section of your slider:

$selectedMin = $minPrice;
$selectedMax = $maxPrice;

So full code update (only this section changes):

$minPrice = $row['min_price'] ?? 0;
$maxPrice = $row['max_price'] ?? 1000;

$selectedMin = $minPrice; // always start at min
$selectedMax = $maxPrice; // always start at max

Now your sliders will load like this:
– 👈 Left thumb starts at `minPrice`
– 👉 Right thumb starts at `maxPrice`

✅ This will reflect in:
– Slider positions
– The blue fill (`range-fill`) line
– Displayed prices below the slider

Let me know if you want:
– Limits (e.g., min must always be ≤ max)
– Tooltips above the thumbs
– Save as default values in DB when editing feed again

Leave a Comment

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