add option to render NumberType as type="number"
This commit is contained in:
parent
346491c672
commit
42e8f5e3a2
@ -170,7 +170,7 @@
|
|||||||
{%- endblock dateinterval_widget -%}
|
{%- endblock dateinterval_widget -%}
|
||||||
|
|
||||||
{%- block number_widget -%}
|
{%- block number_widget -%}
|
||||||
{# type="number" doesn't work with floats #}
|
{# type="number" doesn't work with floats in localized formats #}
|
||||||
{%- set type = type|default('text') -%}
|
{%- set type = type|default('text') -%}
|
||||||
{{ block('form_widget_simple') }}
|
{{ block('form_widget_simple') }}
|
||||||
{%- endblock number_widget -%}
|
{%- endblock number_widget -%}
|
||||||
|
@ -2089,6 +2089,22 @@ abstract class AbstractBootstrap3LayoutTest extends AbstractLayoutTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRenderNumberWithHtml5NumberType()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\NumberType', 1234.56, [
|
||||||
|
'html5' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), ['attr' => ['class' => 'my&class']],
|
||||||
|
'/input
|
||||||
|
[@type="number"]
|
||||||
|
[@name="name"]
|
||||||
|
[@class="my&class form-control"]
|
||||||
|
[@value="1234.56"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testPassword()
|
public function testPassword()
|
||||||
{
|
{
|
||||||
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
|
||||||
|
@ -4,6 +4,7 @@ CHANGELOG
|
|||||||
4.3.0
|
4.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
* added `html5` option to `NumberType` that allows to render `type="number"` input fields
|
||||||
* deprecated using the `date_format`, `date_widget`, and `time_widget` options of the `DateTimeType` when the `widget`
|
* deprecated using the `date_format`, `date_widget`, and `time_widget` options of the `DateTimeType` when the `widget`
|
||||||
option is set to `single_text`
|
option is set to `single_text`
|
||||||
* added `block_prefix` option to `BaseType`.
|
* added `block_prefix` option to `BaseType`.
|
||||||
|
@ -77,8 +77,9 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
|
|||||||
protected $roundingMode;
|
protected $roundingMode;
|
||||||
|
|
||||||
private $scale;
|
private $scale;
|
||||||
|
private $locale;
|
||||||
|
|
||||||
public function __construct(int $scale = null, ?bool $grouping = false, ?int $roundingMode = self::ROUND_HALF_UP)
|
public function __construct(int $scale = null, ?bool $grouping = false, ?int $roundingMode = self::ROUND_HALF_UP, string $locale = null)
|
||||||
{
|
{
|
||||||
if (null === $grouping) {
|
if (null === $grouping) {
|
||||||
$grouping = false;
|
$grouping = false;
|
||||||
@ -91,6 +92,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
|
|||||||
$this->scale = $scale;
|
$this->scale = $scale;
|
||||||
$this->grouping = $grouping;
|
$this->grouping = $grouping;
|
||||||
$this->roundingMode = $roundingMode;
|
$this->roundingMode = $roundingMode;
|
||||||
|
$this->locale = $locale;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,7 +216,7 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
|
|||||||
*/
|
*/
|
||||||
protected function getNumberFormatter()
|
protected function getNumberFormatter()
|
||||||
{
|
{
|
||||||
$formatter = new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL);
|
$formatter = new \NumberFormatter($this->locale ?? \Locale::getDefault(), \NumberFormatter::DECIMAL);
|
||||||
|
|
||||||
if (null !== $this->scale) {
|
if (null !== $this->scale) {
|
||||||
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $this->scale);
|
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $this->scale);
|
||||||
|
@ -12,8 +12,12 @@
|
|||||||
namespace Symfony\Component\Form\Extension\Core\Type;
|
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||||
|
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
|
use Symfony\Component\Form\Exception\LogicException;
|
||||||
use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer;
|
use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
|
use Symfony\Component\Form\FormInterface;
|
||||||
|
use Symfony\Component\Form\FormView;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
class NumberType extends AbstractType
|
class NumberType extends AbstractType
|
||||||
@ -26,10 +30,21 @@ class NumberType extends AbstractType
|
|||||||
$builder->addViewTransformer(new NumberToLocalizedStringTransformer(
|
$builder->addViewTransformer(new NumberToLocalizedStringTransformer(
|
||||||
$options['scale'],
|
$options['scale'],
|
||||||
$options['grouping'],
|
$options['grouping'],
|
||||||
$options['rounding_mode']
|
$options['rounding_mode'],
|
||||||
|
$options['html5'] ? 'en' : null
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function buildView(FormView $view, FormInterface $form, array $options)
|
||||||
|
{
|
||||||
|
if ($options['html5']) {
|
||||||
|
$view->vars['type'] = 'number';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@ -41,6 +56,7 @@ class NumberType extends AbstractType
|
|||||||
'grouping' => false,
|
'grouping' => false,
|
||||||
'rounding_mode' => NumberToLocalizedStringTransformer::ROUND_HALF_UP,
|
'rounding_mode' => NumberToLocalizedStringTransformer::ROUND_HALF_UP,
|
||||||
'compound' => false,
|
'compound' => false,
|
||||||
|
'html5' => false,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$resolver->setAllowedValues('rounding_mode', [
|
$resolver->setAllowedValues('rounding_mode', [
|
||||||
@ -54,6 +70,15 @@ class NumberType extends AbstractType
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$resolver->setAllowedTypes('scale', ['null', 'int']);
|
$resolver->setAllowedTypes('scale', ['null', 'int']);
|
||||||
|
$resolver->setAllowedTypes('html5', 'bool');
|
||||||
|
|
||||||
|
$resolver->setNormalizer('grouping', function (Options $options, $value) {
|
||||||
|
if (true === $value && $options['html5']) {
|
||||||
|
throw new LogicException('Cannot use the "grouping" option when the "html5" option is enabled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1871,6 +1871,23 @@ abstract class AbstractLayoutTest extends FormIntegrationTestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testRenderNumberWithHtml5NumberType()
|
||||||
|
{
|
||||||
|
$this->requiresFeatureSet(403);
|
||||||
|
|
||||||
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\NumberType', 1234.56, [
|
||||||
|
'html5' => true,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertWidgetMatchesXpath($form->createView(), [],
|
||||||
|
'/input
|
||||||
|
[@type="number"]
|
||||||
|
[@name="name"]
|
||||||
|
[@value="1234.56"]
|
||||||
|
'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function testPassword()
|
public function testPassword()
|
||||||
{
|
{
|
||||||
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
|
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
|
||||||
|
@ -75,4 +75,28 @@ class NumberTypeTest extends BaseTypeTest
|
|||||||
$this->assertSame($expectedData, $form->getNormData());
|
$this->assertSame($expectedData, $form->getNormData());
|
||||||
$this->assertSame($expectedData, $form->getData());
|
$this->assertSame($expectedData, $form->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testIgnoresDefaultLocaleToRenderHtml5NumberWidgets()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
'scale' => 2,
|
||||||
|
'rounding_mode' => \NumberFormatter::ROUND_UP,
|
||||||
|
'html5' => true,
|
||||||
|
]);
|
||||||
|
$form->setData(12345.54321);
|
||||||
|
|
||||||
|
$this->assertSame('12345.55', $form->createView()->vars['value']);
|
||||||
|
$this->assertSame('12345.55', $form->getViewData());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException \Symfony\Component\Form\Exception\LogicException
|
||||||
|
*/
|
||||||
|
public function testGroupingNotAllowedWithHtml5Widget()
|
||||||
|
{
|
||||||
|
$this->factory->create(static::TESTED_TYPE, null, [
|
||||||
|
'grouping' => true,
|
||||||
|
'html5' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user