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
20 changes: 15 additions & 5 deletions assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,9 @@ class App {
});
});

document.querySelectorAll('[data-ea-value-of-comparison-id]').forEach((firstValue) => {
firstValue.dataset.eaOriginalInputType = firstValue.type;
});
document.querySelectorAll('[data-ea-comparison-id]').forEach((comparisonWidget) => {
comparisonWidget.addEventListener('change', (event) => {
const comparisonWidget = event.currentTarget;
Expand All @@ -452,14 +455,21 @@ class App {
if (comparisonId === undefined) {
return;
}

const secondValue = document.querySelector(`[data-ea-value2-of-comparison-id="${comparisonId}"]`);
const firstValue = document.querySelector(`[data-ea-value-of-comparison-id="${comparisonId}"]`);

if (secondValue === null) {
return;
if (secondValue !== null) {
toggleVisibilityClasses(secondValue, comparisonWidget.value !== 'between');
}
if (firstValue !== null && firstValue.dataset.eaOriginalInputType === 'number') {
if (comparisonWidget.value === 'in') {
firstValue.type = 'text';
firstValue.placeholder = 'xxx; yyy; zzz';
} else {
firstValue.type = 'number';
firstValue.placeholder = '';
}
}

toggleVisibilityClasses(secondValue, comparisonWidget.value !== 'between');
});
});
}
Expand Down
3 changes: 2 additions & 1 deletion doc/filters.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ These are the built-in filters provided by EasyAdmin:
It's rendered as two radio buttons for the null and not null options.
* ``NumericFilter``: applied by default to numeric fields.
It's rendered as a ``<select>`` list with the condition (higher/lower/equal/etc.) and a
``<input>`` to define the comparison value.
``<input>`` to define the comparison value. When using the ``IN`` comparator, the value
input becomes a text field where you can enter a semicolon-separated list of numbers.
* ``TextFilter``: applied by default to string/text fields. It's rendered as a
``<select>`` list with the condition (contains/not contains/etc.) and an ``<input>`` or
``<textarea>`` to define the comparison value.
Expand Down
36 changes: 29 additions & 7 deletions src/Filter/NumericFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace EasyCorp\Bundle\EasyAdminBundle\Filter;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\ORM\QueryBuilder;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Filter\FilterInterface;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
Expand Down Expand Up @@ -44,18 +45,39 @@ public function apply(QueryBuilder $queryBuilder, FilterDataDto $filterDataDto,
$value = $filterDataDto->getValue();
$value2 = $filterDataDto->getValue2();

if (null !== $fieldDto && true === $fieldDto->getCustomOption(MoneyField::OPTION_STORED_AS_CENTS)) {
$divisor = $fieldDto->getFormTypeOption('divisor') ?? MoneyConfigurator::DEFAULT_DIVISOR;
$value *= $divisor;
$value2 *= $divisor;
}
$storedAsCents = null !== $fieldDto && true === $fieldDto->getCustomOption(MoneyField::OPTION_STORED_AS_CENTS);
$divisor = $storedAsCents ? ($fieldDto->getFormTypeOption('divisor') ?? MoneyConfigurator::DEFAULT_DIVISOR) : 1;

if (ComparisonType::BETWEEN === $comparison) {
$queryBuilder->andWhere(sprintf('%s.%s BETWEEN :%s and :%s', $alias, $property, $parameterName, $parameter2Name))
if ($storedAsCents) {
if (is_numeric($value)) {
$value *= $divisor;
}
if (is_numeric($value2)) {
$value2 *= $divisor;
}
}
$queryBuilder
->andWhere(sprintf('%s.%s BETWEEN :%s and :%s', $alias, $property, $parameterName, $parameter2Name))
->setParameter($parameterName, $value)
->setParameter($parameter2Name, $value2);
} elseif (ComparisonType::IN === $comparison) {
// allow semicolon-separated or array values for 'IN' comparator (supports integers or decimals)
$values = is_iterable($value)
? $value
: array_filter(array_map('trim', explode(';', (string) $value)), static fn (string $v): bool => '' !== $v);
if ($storedAsCents) {
$values = array_map(static fn ($v) => is_numeric($v) ? $v * $divisor : $v, $values);
}
$queryBuilder
->andWhere(sprintf('%s.%s IN (:%s)', $alias, $property, $parameterName))
->setParameter($parameterName, $values, ArrayParameterType::STRING);
} else {
$queryBuilder->andWhere(sprintf('%s.%s %s :%s', $alias, $property, $comparison, $parameterName))
if ($storedAsCents && is_numeric($value)) {
$value *= $divisor;
}
$queryBuilder
->andWhere(sprintf('%s.%s %s :%s', $alias, $property, $comparison, $parameterName))
->setParameter($parameterName, $value);
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/Form/Filter/Type/NumericFilterType.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
use Symfony\Component\Form\CallbackTransformer;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Symfony\Component\Form\Extension\Core\Type\NumberType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
Expand All @@ -34,6 +37,22 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'label' => false,
]);

// switch to a text-based value field when 'IN' comparator is selected
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options): void {
$data = $event->getData();
if (isset($data['comparison']) && ComparisonType::IN === $data['comparison']) {
$form = $event->getForm();
$form->add('value', TextType::class, $options['value_type_options'] + ['label' => false]);
}
});
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options): void {
$data = $event->getData();
if (isset($data['comparison']) && ComparisonType::IN === $data['comparison']) {
$form = $event->getForm();
$form->add('value', TextType::class, $options['value_type_options'] + ['label' => false]);
}
});

$builder->addModelTransformer(new CallbackTransformer(
static fn ($data) => $data,
static function ($data) {
Expand Down
2 changes: 2 additions & 0 deletions src/Form/Type/ComparisonType.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ComparisonType extends AbstractType
public const LT = '<';
public const LTE = '<=';
public const BETWEEN = 'between';
public const IN = 'in';
public const CONTAINS = 'like';
public const NOT_CONTAINS = 'not like';
public const STARTS_WITH = 'like*';
Expand All @@ -38,6 +39,7 @@ public function configureOptions(OptionsResolver $resolver): void
'filter.label.is_greater_than_or_equal_to' => self::GTE,
'filter.label.is_less_than' => self::LT,
'filter.label.is_less_than_or_equal_to' => self::LTE,
'filter.label.is_in' => self::IN,
'filter.label.is_between' => self::BETWEEN,
],
'text' => [
Expand Down
2 changes: 1 addition & 1 deletion templates/crud/form_theme.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@
{% block ea_numeric_filter_widget %}
<div class="form-widget-compound">
{{ form_row(form.comparison) }}
{{ form_row(form.value) }}
{{ form_row(form.value, { attr: form.value.vars.attr|merge({'data-ea-value-of-comparison-id': form.comparison.vars.id}) }) }}
<div data-ea-value2-of-comparison-id="{{ form.comparison.vars.id }}" class="{{ form.comparison.vars.value != 'between' ? 'd-none' }}">
{{ form_row(form.value2) }}
</div>
Expand Down
10 changes: 10 additions & 0 deletions tests/Form/Filter/Type/NumericFilterTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

namespace EasyCorp\Bundle\EasyAdminBundle\Tests\Form\Filter\Type;

use Doctrine\DBAL\ArrayParameterType;
use Doctrine\ORM\Query\Parameter;
use EasyCorp\Bundle\EasyAdminBundle\Form\Filter\Type\NumericFilterType;
use EasyCorp\Bundle\EasyAdminBundle\Form\Type\ComparisonType;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\StringType;

class NumericFilterTypeTest extends FilterTypeTest
{
Expand Down Expand Up @@ -82,5 +84,13 @@ public static function getDataProvider(): iterable
[],
'Unable to reverse value for field path "easyadmin_numeric_filter": Two values must be provided when "BETWEEN" comparison is selected.',
];

yield [
['comparison' => ComparisonType::IN, 'value' => '1;2;3', 'value2' => null],
['comparison' => 'in', 'value' => '1;2;3', 'value2' => null],
['value_type' => StringType::class],
'SELECT o FROM Object o WHERE o.foo IN (:foo_1)',
[new Parameter('foo_1', ['1', '2', '3'], ArrayParameterType::STRING)],
];
}
}
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.ar.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'اكبر من او يساوي',
'label.is_less_than' => 'أصغر من',
'label.is_less_than_or_equal_to' => 'أصغر من أو يساوي',
'label.is_in' => 'ي',
'label.is_between' => 'بين',
'label.contains' => 'يحتوي',
'label.not_contains' => 'لا يحتوي',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.bg.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'е по-голямо или равно на',
'label.is_less_than' => 'е по-малко от',
'label.is_less_than_or_equal_to' => 'е по-малко или равно на',
'label.is_in' => 'е в',
'label.is_between' => 'е между',
'label.contains' => 'съдържа',
'label.not_contains' => 'не съдържа',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.ca.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'és més gran o igual a',
'label.is_less_than' => 'és menor que',
'label.is_less_than_or_equal_to' => 'és menor o igual a',
'label.is_in' => 'està a',
'label.is_between' => 'està entre',
'label.contains' => 'conté',
'label.not_contains' => 'no conté',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.cs.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'je větší než nebo rovno',
'label.is_less_than' => 'je menší než',
'label.is_less_than_or_equal_to' => 'je menší než nebo rovno',
'label.is_in' => 'je v',
'label.is_between' => 'je mezi',
'label.contains' => 'obsahuje',
'label.not_contains' => 'neobsahuje',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.da.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'er større end eller lig med',
'label.is_less_than' => 'er mindre end',
'label.is_less_than_or_equal_to' => 'er mindre end eller lig med',
'label.is_in' => 'er i',
'label.is_between' => 'er i mellem',
'label.contains' => 'indeholder',
'label.not_contains' => 'indeholder ikke',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.de.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'ist größer oder gleich',
'label.is_less_than' => 'ist kleiner als',
'label.is_less_than_or_equal_to' => 'ist kleiner oder gleich',
'label.is_in' => 'ist in',
'label.is_between' => 'ist zwischen',
'label.contains' => 'enthält',
'label.not_contains' => 'enthält nicht',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.el.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'είναι μεγαλύτερο ή ίσο με',
'label.is_less_than' => 'είναι μικρότερο από',
'label.is_less_than_or_equal_to' => 'είναι μικρότερο ή ίσο με',
'label.is_in' => 'είναι σε',
'label.is_between' => 'είναι μεταξύ',
'label.contains' => 'περιέχει',
'label.not_contains' => 'δεν περιέχει',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.en.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'is greater than or equal to',
'label.is_less_than' => 'is less than',
'label.is_less_than_or_equal_to' => 'is less than or equal to',
'label.is_in' => 'is in',
'label.is_between' => 'is between',
'label.contains' => 'contains',
'label.not_contains' => 'doesn\'t contain',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.es.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'es mayor o igual que',
'label.is_less_than' => 'es menor que',
'label.is_less_than_or_equal_to' => 'es menor o igual que',
'label.is_in' => 'está en',
'label.is_between' => 'está entre',
'label.contains' => 'contiene',
'label.not_contains' => 'no contiene',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.eu.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'handiagoa edo berdina da',
'label.is_less_than' => 'baino txikiagoa da',
'label.is_less_than_or_equal_to' => 'txikiagoa edo berdina da',
'label.is_in' => 'barruan dago',
'label.is_between' => 'tartean dago',
'label.contains' => 'dauka',
'label.not_contains' => 'ez dauka',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.fa.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'بزرگتر یا مساوی با',
'label.is_less_than' => 'کوچکتر از',
'label.is_less_than_or_equal_to' => 'کوچکتر یا مساوی با',
'label.is_in' => ' در',
'label.is_between' => 'در بین',
'label.contains' => 'شامل',
'label.not_contains' => 'شامل نمی‌شود',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.fi.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
// 'label.is_greater_than_or_equal_to' => '',
// 'label.is_less_than' => '',
// 'label.is_less_than_or_equal_to' => '',
// 'label.is_in' => 'on',
// 'label.is_between' => '',
// 'label.contains' => '',
// 'label.not_contains' => '',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.fr.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'est supérieur(e) ou égal(e) à',
'label.is_less_than' => 'est inférieur(e) à',
'label.is_less_than_or_equal_to' => 'est inférieur(e) ou égal(e) à',
'label.is_in' => 'est dans',
'label.is_between' => 'est entre',
'label.contains' => 'contient',
'label.not_contains' => 'ne contient pas',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.gl.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
// 'label.is_greater_than_or_equal_to' => '',
// 'label.is_less_than' => '',
// 'label.is_less_than_or_equal_to' => '',
// 'label.is_in' => 'está en',
// 'label.is_between' => '',
// 'label.contains' => '',
// 'label.not_contains' => '',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.he.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'גדול/שווה לערך',
'label.is_less_than' => 'קטן מהערך',
'label.is_less_than_or_equal_to' => 'קטן/שווה לערך',
'label.is_in' => 'נמצא ב',
'label.is_between' => 'בין',
'label.contains' => 'מכיל',
'label.not_contains' => 'לא מכיל',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.hr.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
// 'label.is_greater_than_or_equal_to' => '',
// 'label.is_less_than' => '',
// 'label.is_less_than_or_equal_to' => '',
'label.is_in' => 'je u',
// 'label.is_between' => '',
// 'label.contains' => '',
// 'label.not_contains' => '',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.hu.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'nagyobb vagy egyenlő',
'label.is_less_than' => 'kisebb',
'label.is_less_than_or_equal_to' => 'kisebb vagy egyenlő',
'label.is_in' => 'is in',
'label.is_between' => 'kettő között',
'label.contains' => 'tartalmazza',
'label.not_contains' => 'nem tartalmazza',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.hy.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'մեծ է կամ հավասար է',
'label.is_less_than' => 'փոքր է',
'label.is_less_than_or_equal_to' => 'փոքր է կամ հավասար է',
'label.is_in' => 'գտնվում է',
'label.is_between' => 'միջակայքում է',
'label.contains' => 'պարունակում է',
'label.not_contains' => 'չի պարունակում',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.id.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'lebih besar atau sama dengan',
'label.is_less_than' => 'kurang dari',
'label.is_less_than_or_equal_to' => 'kurang dari atau sama dengan',
'label.is_in' => 'ada di',
'label.is_between' => 'antara',
'label.contains' => 'mengandung',
'label.not_contains' => 'tidak mengandung',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.it.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'è maggiore o uguale di',
'label.is_less_than' => 'è minore di',
'label.is_less_than_or_equal_to' => 'è minore o uguale di',
'label.is_in' => 'è in',
'label.is_between' => 'è tra',
'label.contains' => 'contiene',
'label.not_contains' => 'non contiene',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.lb.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'ass gréisser wéi oder gläich',
'label.is_less_than' => 'ass méi kleng wéi',
'label.is_less_than_or_equal_to' => 'ass méi kleng wéi oder gläich',
'label.is_in' => 'ass an',
'label.is_between' => 'ass tëscht',
'label.contains' => 'enthält',
'label.not_contains' => 'enthält net',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.lt.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'didesnis arba lygus',
'label.is_less_than' => 'mažesnis',
'label.is_less_than_or_equal_to' => 'mažesnis arba lygus',
'label.is_in' => 'yra',
'label.is_between' => 'tarp',
'label.contains' => 'turi',
'label.not_contains' => 'neturi',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.mk.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'е поголемо или еднакво со',
'label.is_less_than' => 'е помало од',
'label.is_less_than_or_equal_to' => 'е помало или еднакво со',
'label.is_in' => 'е во',
'label.is_between' => 'е помеѓу',
'label.contains' => 'содржи',
'label.not_contains' => 'не содржи',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.nl.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'is groter dan of gelijk aan',
'label.is_less_than' => 'is minder dan',
'label.is_less_than_or_equal_to' => 'is minder dan of gelijk aan',
'label.is_in' => 'zit in',
'label.is_between' => 'ligt tussen',
'label.contains' => 'bevat',
'label.not_contains' => 'bevat niet',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.no.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'er større eller lik som',
'label.is_less_than' => 'er mindre enn',
'label.is_less_than_or_equal_to' => 'er mindre enn eller lik som',
'label.is_in' => 'er i',
'label.is_between' => 'er mellom',
'label.contains' => 'inneholder',
'label.not_contains' => 'inneholder ikke',
Expand Down
1 change: 1 addition & 0 deletions translations/EasyAdminBundle.pl.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
'label.is_greater_than_or_equal_to' => 'większy lub równy',
'label.is_less_than' => 'mniejszy niż',
'label.is_less_than_or_equal_to' => 'mniejszy lub równy',
'label.is_in' => 'jest w',
'label.is_between' => 'pomiędzy',
'label.contains' => 'zawiera',
'label.not_contains' => 'nie zawiera',
Expand Down
Loading