Skip to content

Commit

Permalink
feature #30267 [Form] add option to render NumberType as type="number…
Browse files Browse the repository at this point in the history
…" (xabbuh)

This PR was merged into the 4.3-dev branch.

Discussion
----------

[Form] add option to render NumberType as type="number"

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #8106
| License       | MIT
| Doc PR        | symfony/symfony-docs#10997

Commits
-------

42e8f5e add option to render NumberType as type="number"
  • Loading branch information
fabpot committed Feb 21, 2019
2 parents 02d6c0f + 42e8f5e commit 6207f19
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 4 deletions.
Expand Up @@ -170,7 +170,7 @@
{%- endblock dateinterval_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') -%}
{{ block('form_widget_simple') }}
{%- endblock number_widget -%}
Expand Down
Expand Up @@ -2089,6 +2089,22 @@ public function testNumber()
);
}

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()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ CHANGELOG
exception in 5.0.
* Using names for buttons that do not contain only letters, digits, underscores, hyphens, and colons is deprecated and
will lead to an exception in 5.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`
option is set to `single_text`
* added `block_prefix` option to `BaseType`.
Expand Down
Expand Up @@ -77,8 +77,9 @@ class NumberToLocalizedStringTransformer implements DataTransformerInterface
protected $roundingMode;

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) {
$grouping = false;
Expand All @@ -91,6 +92,7 @@ public function __construct(int $scale = null, ?bool $grouping = false, ?int $ro
$this->scale = $scale;
$this->grouping = $grouping;
$this->roundingMode = $roundingMode;
$this->locale = $locale;
}

/**
Expand Down Expand Up @@ -214,7 +216,7 @@ public function reverseTransform($value)
*/
protected function getNumberFormatter()
{
$formatter = new \NumberFormatter(\Locale::getDefault(), \NumberFormatter::DECIMAL);
$formatter = new \NumberFormatter($this->locale ?? \Locale::getDefault(), \NumberFormatter::DECIMAL);

if (null !== $this->scale) {
$formatter->setAttribute(\NumberFormatter::FRACTION_DIGITS, $this->scale);
Expand Down
27 changes: 26 additions & 1 deletion src/Symfony/Component/Form/Extension/Core/Type/NumberType.php
Expand Up @@ -12,8 +12,12 @@
namespace Symfony\Component\Form\Extension\Core\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Exception\LogicException;
use Symfony\Component\Form\Extension\Core\DataTransformer\NumberToLocalizedStringTransformer;
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;

class NumberType extends AbstractType
Expand All @@ -26,10 +30,21 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$builder->addViewTransformer(new NumberToLocalizedStringTransformer(
$options['scale'],
$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}
*/
Expand All @@ -41,6 +56,7 @@ public function configureOptions(OptionsResolver $resolver)
'grouping' => false,
'rounding_mode' => NumberToLocalizedStringTransformer::ROUND_HALF_UP,
'compound' => false,
'html5' => false,
]);

$resolver->setAllowedValues('rounding_mode', [
Expand All @@ -54,6 +70,15 @@ public function configureOptions(OptionsResolver $resolver)
]);

$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;
});
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
Expand Up @@ -1871,6 +1871,23 @@ public function testNumber()
);
}

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()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\PasswordType', 'foo&bar');
Expand Down
Expand Up @@ -75,4 +75,28 @@ public function testSubmitNullUsesDefaultEmptyData($emptyData = '10', $expectedD
$this->assertSame($expectedData, $form->getNormData());
$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,
]);
}
}

0 comments on commit 6207f19

Please sign in to comment.