Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ GitHub contributors:
- matrix
- raph
- sadlyblue
- vachmara
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This module is partially compatible with the multistore feature. Some of its opt

## Reporting issues

You can report issues with this module in the main PrestaShop repository. [Click here to report an issue][report-issue].
You can report issues with this module in the main PrestaShop repository. [Click here to report an issue][report-issue].

## Requirements

Expand Down
56 changes: 40 additions & 16 deletions _dev/front/slider.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,20 @@ import NumberFormatter from '../cldr/number-formatter';

const formatters = {};

const displayLabelBlock = (formatterId, displayBlock, min, max) => {
const displayLabelBlock = (formatterId, displayBlock, min, max, isCustomSlider = false) => {
if (formatters[formatterId] === undefined) {
displayBlock.text(
displayBlock.text().replace(
/([^\d]*)(?:[\d\s.,]+)([^\d]+)(?:[\d\s.,]+)(.*)/,
`$1${min}$2${max}$3`,
),
);
// For standard numeric range sliders
if (!isCustomSlider) {
displayBlock.text(
displayBlock.text().replace(
/([^\d]*)(?:[\d\s.,]+)([^\d]+)(?:[\d\s.,]+)(.*)/,
`$1${min}$2${max}$3`,
),
);
} else {
// For non-range filter sliders, adapt the display
displayBlock.text(`${min} - ${max}`);
}
} else {
displayBlock.text(
`${formatters[formatterId].format(min)} - ${formatters[formatterId].format(max)}`,
Expand All @@ -45,6 +51,19 @@ const refreshSliders = () => {
const $el = $(this);
const values = $el.data('slider-values');
const specifications = $el.data('slider-specifications');
const isCustomSlider = $el.data('slider-type') === 'custom';
const minValue = $el.data('slider-min');
const maxValue = $el.data('slider-max');

// Make sure we have valid min and max values
if (minValue === undefined || maxValue === undefined) {
console.warn(`Slider ${$el.data('slider-id')} is missing min or max values`);
return; // Skip this slider
}

// If values is null, undefined, or not an array, initialize with min/max values
const startValues = Array.isArray(values) && values.length === 2
? values : [minValue, maxValue];

if (specifications !== null && specifications !== undefined) {
formatters[$el.data('slider-id')] = NumberFormatter.build(specifications);
Expand All @@ -53,20 +72,24 @@ const refreshSliders = () => {
displayLabelBlock(
$el.data('slider-id'),
$(`#facet_label_${$el.data('slider-id')}`),
values === null ? $el.data('slider-min') : values[0],
values === null ? $el.data('slider-max') : values[1],
startValues[0],
startValues[1],
isCustomSlider,
);

$(`#slider-range_${$el.data('slider-id')}`).slider({
range: true,
min: $el.data('slider-min'),
max: $el.data('slider-max'),
values: [
values === null ? $el.data('slider-min') : values[0],
values === null ? $el.data('slider-max') : values[1],
],
min: minValue,
max: maxValue,
values: startValues,
stop(event, ui) {
const nextEncodedFacetsURL = $el.data('slider-encoded-url');

if (!nextEncodedFacetsURL) {
console.warn(`Slider ${$el.data('slider-id')} is missing encoded URL data`);
return;
}

const urlsSplitted = nextEncodedFacetsURL.split('?');
let queryParams = [];

Expand Down Expand Up @@ -94,7 +117,7 @@ const refreshSliders = () => {
query.value.length > 0 ? '/' : '',
$el.data('slider-label'),
'-',
$el.data('slider-unit'),
isCustomSlider ? '' : $el.data('slider-unit'),
'-',
ui.values[0],
'-',
Expand All @@ -120,6 +143,7 @@ const refreshSliders = () => {
$(`#facet_label_${$el.data('slider-id')}`),
ui.values[0],
ui.values[1],
isCustomSlider,
);
},
});
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
},
"homepage": "https://github.com/PrestaShop/ps_facetedsearch#readme",
"devDependencies": {
"@babel/eslint-parser": "^7.25.8",
"@babel/cli": "^7.26.4",
"@babel/core": "^7.24.9",
"@babel/eslint-parser": "^7.25.8",
"@babel/node": "^7.24.8",
"@babel/preset-env": "^7.25.8",
"@babel/register": "^7.23.7",
Expand All @@ -54,5 +54,11 @@
"dependencies": {
"jquery-ui-touch-punch": "^0.2.3",
"lodash.escaperegexp": "^4.1.2"
},
"pnpm": {
"onlyBuiltDependencies": [
"core-js",
"node-sass"
]
}
}
10 changes: 10 additions & 0 deletions ps_facetedsearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,15 @@ public function renderAdminTemplateEdit($template = null)
->setRootCategory((Shop::getContext() == Shop::CONTEXT_SHOP ? Category::getRootCategory()->id_category : 0))
->setUseCheckBox(true);

// Create a Converter instance to check for numeric values
$filterConverter = new PrestaShop\Module\FacetedSearch\Filters\Converter(
$this->context,
$this->getDatabase(),
new PrestaShop\Module\FacetedSearch\URLSerializer(),
new PrestaShop\Module\FacetedSearch\Filters\DataAccessor($this->getDatabase()),
new PrestaShop\Module\FacetedSearch\Filters\Provider($this->getDatabase())
);

// If we are editing an already existing template, we will load its data,
// check categories and add selected filters. Otherwise, we prepare empty template.
if ($template !== null) {
Expand Down Expand Up @@ -877,6 +886,7 @@ public function renderAdminTemplateEdit($template = null)
'default_filters' => $this->getDefaultFilters(),
'categories_tree' => $treeCategoriesHelper->render(),
'controller_options' => $controller_options,
'filterConverter' => $filterConverter,
]);

// We are using two separate templates depending on context
Expand Down
39 changes: 32 additions & 7 deletions src/Filters/Block.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@
use Configuration;
use Context;
use Db;
use Feature;
use Group;
use Manufacturer;
use PrestaShop\Module\FacetedSearch\Adapter\InterfaceAdapter;
use PrestaShop\Module\FacetedSearch\Definition\Availability;
use PrestaShop\Module\FacetedSearch\Product\Search;
use PrestaShop\PrestaShop\Core\Localization\Locale;
use PrestaShop\PrestaShop\Core\Localization\Specification\NumberSymbolList;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShopDatabaseException;

Expand Down Expand Up @@ -92,7 +90,7 @@ public function __construct(
DataAccessor $dataAccessor,
ProductSearchQuery $query,
Provider $provider
) {
) {
$this->searchAdapter = $searchAdapter;
$this->context = $context;
$this->database = $database;
Expand Down Expand Up @@ -397,7 +395,8 @@ private function getConditionsBlock($filter, $selectedFilters)
$count = $values['c'];

$conditionArray[$condition]['nbr'] = $count;
if (isset($selectedFilters['condition'])
if (
isset($selectedFilters['condition'])
&& in_array($condition, $selectedFilters['condition'])
) {
$conditionArray[$condition]['checked'] = true;
Expand Down Expand Up @@ -579,8 +578,8 @@ private function getHighlightsBlock($filter, $selectedFilters)
'Y-m-d 00:00:00',
strtotime(
((int) Configuration::get('PS_NB_DAYS_NEW_PRODUCT') > 0 ?
'-' . ((int) Configuration::get('PS_NB_DAYS_NEW_PRODUCT') - 1) . ' days' :
'+ 1 days')
'-' . ((int) Configuration::get('PS_NB_DAYS_NEW_PRODUCT') - 1) . ' days' :
'+ 1 days')
)
);
$filteredSearchAdapter->addFilter('date_add', ["'" . $timeCondition . "'"], '>');
Expand Down Expand Up @@ -675,7 +674,8 @@ private function getManufacturersBlock($filter, $selectedFilters, $idLang)
'nbr' => $count,
];

if (isset($selectedFilters['manufacturer'])
if (
isset($selectedFilters['manufacturer'])
&& in_array($id_manufacturer, $selectedFilters['manufacturer'])
) {
$manufacturersArray[$id_manufacturer]['checked'] = true;
Expand Down Expand Up @@ -853,6 +853,7 @@ private function getFeaturesBlock($filter, $selectedFilters, $idLang)

$filteredSearchAdapter->addSelectField('id_feature');
$results = $filteredSearchAdapter->valueCount('id_feature_value');

foreach ($results as $key => $values) {
$idFeatureValue = $values['id_feature_value'];
$idFeature = $values['id_feature'];
Expand All @@ -863,6 +864,26 @@ private function getFeaturesBlock($filter, $selectedFilters, $idLang)
if (!isset($featureBlock[$idFeature])) {
$features[$idFeature]['featureValues'] = $this->dataAccessor->getFeatureValues($idFeature, $idLang);

// --- Begin min/max calculation for slider features ---
$isSlider = isset($filter['filter_type']) && $filter['filter_type'] == Converter::WIDGET_TYPE_SLIDER;
$minValue = null;
$maxValue = null;
if ($isSlider) {
$featureValuesAll = $this->dataAccessor->getFeatureValues($idFeature, $idLang);
foreach ($featureValuesAll as $fv) {
if (isset($fv['value']) && preg_match('/[0-9]+(\.[0-9]+)?/', (string) $fv['value'], $matches)) {
$val = (float) $matches[0];
if ($minValue === null || $val < $minValue) {
$minValue = $val;
}
if ($maxValue === null || $val > $maxValue) {
$maxValue = $val;
}
}
}
}
// --- End min/max calculation ---

$featureBlock[$idFeature] = [
'type_lite' => 'id_feature',
'type' => 'id_feature',
Expand All @@ -873,6 +894,10 @@ private function getFeaturesBlock($filter, $selectedFilters, $idLang)
'meta_title' => $feature['meta_title'],
'filter_show_limit' => (int) $filter['filter_show_limit'],
'filter_type' => $filter['filter_type'],
// Always set min/max for slider, otherwise use selectedFilters
'min' => $isSlider ? $minValue : null,
'max' => $isSlider ? $maxValue : null,
'value' => $selectedFilters['id_feature'][$idFeature]['value'] ?? null,
];
}

Expand Down
Loading