diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
index 0b301b42cc4ad..03109bdf6cac2 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig
@@ -106,12 +106,16 @@
{%- endblock dateinterval_widget %}
{% block percent_widget -%}
-
- {{- block('form_widget_simple') -}}
-
+ {%- else -%}
+ {{- block('form_widget_simple') -}}
+ {%- endif -%}
{%- endblock percent_widget %}
{% block file_widget -%}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
index 136cabccb19ed..a6ee019a094b6 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig
@@ -26,10 +26,14 @@
{%- endblock money_widget %}
{% block percent_widget -%}
-
+ {%- endif -%}
{%- endblock percent_widget %}
{% block datetime_widget -%}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
index 52a639a33365f..1d7ad1c328649 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
@@ -196,7 +196,7 @@
{%- block percent_widget -%}
{%- set type = type|default('text') -%}
- {{ block('form_widget_simple') }} %
+ {{ block('form_widget_simple') }}{% if symbol %} {{ symbol|default('%') }}{% endif %}
{%- endblock percent_widget -%}
{%- block password_widget -%}
diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
index 3ae67935fb758..9547ea4900fe6 100644
--- a/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
+++ b/src/Symfony/Bridge/Twig/Resources/views/Form/foundation_5_layout.html.twig
@@ -43,12 +43,18 @@
{% block percent_widget -%}
-
- {{- block('form_widget_simple') -}}
-
-
- %
-
+ {%- if symbol -%}
+
+ {{- block('form_widget_simple') -}}
+
+
+ {{ symbol|default('%') }}
+
+ {%- else -%}
+
+ {{- block('form_widget_simple') -}}
+
+ {%- endif -%}
{%- endblock percent_widget %}
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
index 254f9a4d1fc6b..489030cd7af12 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap3LayoutTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Bridge\Twig\Tests\Extension;
+use Symfony\Component\Form\Extension\Core\Type\PercentType;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\Tests\AbstractLayoutTest;
@@ -2173,6 +2174,41 @@ public function testPercent()
);
}
+ public function testPercentNoSymbol()
+ {
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => false]);
+ $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
+'/input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="10"]
+'
+ );
+ }
+
+ public function testPercentCustomSymbol()
+ {
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => '‱']);
+ $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
+'/div
+ [@class="input-group"]
+ [
+ ./input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="10"]
+ /following-sibling::span
+ [@class="input-group-addon"]
+ [contains(.., "‱")]
+ ]
+'
+ );
+ }
+
public function testCheckedRadio()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', true);
diff --git a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
index d2263ea870217..89fbacf2fc2d7 100644
--- a/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
+++ b/src/Symfony/Bridge/Twig/Tests/Extension/AbstractBootstrap4LayoutTest.php
@@ -1082,7 +1082,7 @@ public function testMoney()
]);
$this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
- '/div
+'/div
[@class="input-group"]
[
./div
@@ -1108,7 +1108,7 @@ public function testPercent()
$form = $this->factory->createNamed('name', PercentType::class, 0.1);
$this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
- '/div
+'/div
[@class="input-group"]
[
./input
@@ -1125,6 +1125,45 @@ public function testPercent()
[contains(.., "%")]
]
]
+'
+ );
+ }
+
+ public function testPercentNoSymbol()
+ {
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => false]);
+ $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
+'/input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="10"]
+'
+ );
+ }
+
+ public function testPercentCustomSymbol()
+ {
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => '‱']);
+ $this->assertWidgetMatchesXpath($form->createView(), ['id' => 'my&id', 'attr' => ['class' => 'my&class']],
+'/div
+ [@class="input-group"]
+ [
+ ./input
+ [@id="my&id"]
+ [@type="text"]
+ [@name="name"]
+ [@class="my&class form-control"]
+ [@value="10"]
+ /following-sibling::div
+ [@class="input-group-append"]
+ [
+ ./span
+ [@class="input-group-text"]
+ [contains(.., "‱")]
+ ]
+ ]
'
);
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php
index f5839ebf70203..56b417f1d5b5c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/percent_widget.html.php
@@ -1 +1,2 @@
-block($form, 'form_widget_simple', ['type' => isset($type) ? $type : 'text']) ?> %
+
+block($form, 'form_widget_simple', ['type' => isset($type) ? $type : 'text']).$symbol ?>
diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md
index f1b399cedc8be..409153d2be94d 100644
--- a/src/Symfony/Component/Form/CHANGELOG.md
+++ b/src/Symfony/Component/Form/CHANGELOG.md
@@ -4,6 +4,7 @@ CHANGELOG
4.3.0
-----
+ * added a `symbol` option to the `PercentType` that allows to disable or customize the output of the percent character
* Using the `format` option of `DateType` and `DateTimeType` when the `html5` option is enabled is deprecated.
* Using names for buttons that do not start with a letter, a digit, or an underscore is deprecated and will lead to an
exception in 5.0.
diff --git a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php
index dedb9e8cdd1cb..bd141a93697d4 100644
--- a/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php
+++ b/src/Symfony/Component/Form/Extension/Core/Type/PercentType.php
@@ -14,6 +14,8 @@
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\DataTransformer\PercentToLocalizedStringTransformer;
use Symfony\Component\Form\FormBuilderInterface;
+use Symfony\Component\Form\FormInterface;
+use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class PercentType extends AbstractType
@@ -26,6 +28,14 @@ public function buildForm(FormBuilderInterface $builder, array $options)
$builder->addViewTransformer(new PercentToLocalizedStringTransformer($options['scale'], $options['type']));
}
+ /**
+ * {@inheritdoc}
+ */
+ public function buildView(FormView $view, FormInterface $form, array $options)
+ {
+ $view->vars['symbol'] = $options['symbol'];
+ }
+
/**
* {@inheritdoc}
*/
@@ -33,6 +43,7 @@ public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'scale' => 0,
+ 'symbol' => '%',
'type' => 'fractional',
'compound' => false,
]);
@@ -43,6 +54,7 @@ public function configureOptions(OptionsResolver $resolver)
]);
$resolver->setAllowedTypes('scale', 'int');
+ $resolver->setAllowedTypes('symbol', ['bool', 'string']);
}
/**
diff --git a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
index 5b4b84e9e5b99..c85b449346672 100644
--- a/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
+++ b/src/Symfony/Component/Form/Tests/AbstractLayoutTest.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Tests;
use PHPUnit\Framework\SkippedTestError;
+use Symfony\Component\Form\Extension\Core\Type\PercentType;
use Symfony\Component\Form\Extension\Csrf\CsrfExtension;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormView;
@@ -1945,6 +1946,36 @@ public function testPercent()
);
}
+ public function testPercentNoSymbol()
+ {
+ $this->requiresFeatureSet(403);
+
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => false]);
+ $this->assertWidgetMatchesXpath($form->createView(), [],
+'/input
+ [@type="text"]
+ [@name="name"]
+ [@value="10"]
+ [not(contains(.., "%"))]
+'
+ );
+ }
+
+ public function testPercentCustomSymbol()
+ {
+ $this->requiresFeatureSet(403);
+
+ $form = $this->factory->createNamed('name', PercentType::class, 0.1, ['symbol' => '‱']);
+ $this->assertWidgetMatchesXpath($form->createView(), [],
+'/input
+ [@type="text"]
+ [@name="name"]
+ [@value="10"]
+ [contains(.., "‱")]
+'
+ );
+ }
+
public function testCheckedRadio()
{
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\RadioType', true);