Show decimal percent type field - symfony

I'm trying to show a form which has a percent type field that can show values like 3.03% for exemple. But it seems to be rounding to integers, e.g 3% in this case.
Entity field :
/**
* #var float
* #ORM\Column(type="float")
*/
private $penaltyRate;
Form builder :
...
->add('penaltyRate', PercentType::class, ['label' => 'create.form.penalty'])
Is this a limitation of percentType and should I just use another type and add manually the '%' indicator ?
EDIT
For future googler, while #Emanuel Oster was right for just pointing to the official symfony documentation, as it wasn't obvious for me the first time I read it here is an example if you want to allow two decimals :
Form builder :
...
->add('penaltyRate', PercentType::class, [
'label' => 'create.form.penalty',
'scale' => 2
])

From the symfony documentation:
scale
type: integer default: 0
By default, the input numbers are rounded. To allow for more decimal
places, use this option.

Try This
->add('penaltyRate', PercentType::class,[
'label_format' => 'penaltyRate',
'scale'=>1, // or 'scale'=>2
'type'=>'integer'
])

Related

What does the constraint Required do?

What does the constraint Required do in the form builder? If a field was not submitted (not empty value!), I don't receive a corresponding error message. This field is just ignored.
$builder
->add('firstname', TextType::class, [ 'constraints' => [new NotBlank()], 'required'=>true])
->add('lastname', TextType::class, [ 'constraints' => [new NotBlank(),] ,'required'=>true])
How can say, that the field always MUST be submitted?
Thank you.
Required mean your field need a value tu be be submitted. It's similar to the HTML behaviour.
EDIT:
https://symfony.com/doc/current/reference/forms/types/form.html#constraints
https://symfony.com/doc/current/form/without_class.html#form-option-constraints
The issue is on your constraints, I don't know for sure but if adding those to your form don't fix your problem, have a look att adding assert to your Entity attached to your form
https://symfony.com/doc/current/reference/constraints/NotBlank.html
Then validate this entity in your controller
https://symfony.com/doc/current/validation.html
And relying on this you might add errors to the form.
A colleague has found the solution:
In the related entity, you need to define a callback-function like this:
/**
* Check bank account by "CUSTOMER" - not null
* Because NotNull() not working in form type!
* #Assert\Callback()
*/
public function validateBankaccount(ExecutionContextInterface $context)
{
if ($this->type == self::TYPE_CUSTOMER && is_null($this->bankAccount)) {
$context->buildViolation('Bank account is required!')
->atPath('bankAccount')
->addViolation();
}
}

LessThanOrEqual Date without time

I try to validate a Date (not DateTime)
in my validator, i have :
myDate:
- Date: ~
- LessThanOrEqual:
value: today
message: "myDate must be less or equal than today."
Before submitting my form, i send this date to my API (i use symfony as an API with FOSRestBundle):
myDate:"2017-06-09T00:00:00.000Z"
But when i look Symfony\Component\Validator\Constraints\LessThanOrEqualValidator in this method :
protected function compareValues($value1, $value2)
{
return $value1 <= $value2;
}
i have these values:
$value1
DateTime::__set_state(array(
'date' => '2017-06-09 02:00:00.000000',
'timezone_type' => 3,
'timezone' => 'Europe/Paris',
))
$value2
DateTime::__set_state(array(
'date' => '2017-06-09 00:00:00.000000',
'timezone_type' => 3,
'timezone' => 'Europe/Paris',
))
And my validation fails.
Can you help me to solve this problem. I don't need time, i just want to validate the Date. How can i remove the 2 hours ?
Thanks
EDIT :
In my php.ini, i have :
date.timezone ="Europe/Paris"
I solved the problem by sending the right time
First of all LessThanOrEqual do just what its names stands for. It compares if left operand is less or equal to the right operand. No matter if it's a \DateTime or int or something else.
Since you validating \DeteTime i'd suggest you to use Callback Constraint or Expression Constraint so you can define how to validate those. My personal choice for this usecase would be the validation via POST_SUBMIT event in you FormType. See - How to add validators on the fly in Symfony2?

The OptionsResolver component and extra options

I have an array which can have various keys. However, always exists two keys which are required. I use the OptionsResolver component now. It is works fine until there is no any extra keys. I also considered the Validator component and as I understood there is the same behaviour. So I need always set the full list of keys but as I wrote above I need validate only some of them. Is there a way to solve this problem?
Thanks!
Hello you can define required, optional and defaults values in OptionResolver.
Maybe I will give you some example so it will be easier than describing it:
$resolver = new Symfony\Component\OptionsResolver\OptionsResolver;
$resolver
->setRequired(['required1', 'required2'])
->setOptional(['optional1', 'optional2'])
->setDefaults(['defaultValue' => '123'])
;
$options = $resolver->resolve(
[
'required1' => 'test',
'required2' => 'test123',
'optional1' => 'opt'
]
);
then options will be looks like that
[
'defaultValue' => '123',
'required1' => 'test',
'required2' => 'test123',
'optional1' => 'opt',
]
if we do not set required1 or required2 in resolved array then we gotSymfony\Component\OptionsResolver\Exception\MissingOptionsException exception.
If we give not know option (not defined in setRequired, setOptional or setDefaults) then we got Symfony\Component\OptionsResolver\Exception\InvalidOptionsException exception.
I also considered the Validator component and as I understood there is the same behaviour
You can decide which values should be "required"... but not sure if I got what you mean exactly

Disable auto translation for input values in Symfony 2

Symfony2 automatically translate the input field values with type decimal or integer.
I have a two languages for my app: arabic and english
I created an Entity with the following field:
/**
* #var float $price
*
* #ORM\Column(name="price", type="decimal", scale=2, nullable=true)
*
* #Assert\Regex(pattern="/^[0-9]+(\.\d{1,2})?$/",message="Incorrect price.")
* #Assert\Type(type="float")
* #Assert\Min(0)
*/
private $price;
In form I let the sf to guess a field type:
$builder->add('price')
I load the form for editing this entity in Arabic Interface.
In the price field I see ١٢٫٤ instead of 12.40.
I can't save the form because HTML5 validation is failed.
If I enter 12.40 in the current field and save Entity, 12 will be saved, instead of 12.40.
Why? How to disable it? how to validate the Arabic digits?
Any suggestions?
EDIT: solved, see below
I found the answer why it happens here
As you can see, symfony register a ViewTransformer for these widget types:
$builder->addViewTransformer(
new IntegerToLocalizedStringTransformer(
$options['precision'],
$options['grouping'],
$options['rounding_mode']
));
Current transformer transform an integer value to localized string. It happens for the number widget (NumberToLocalizedStringTransformer) and money widget (MoneyToLocalizedStringTransformer) too.
So I think need to register a new FieldType which will not used a ViewTransformer.
EDIT: I solved the problem just disabling intl extension and now all numeric fields are using a default english numbers. If you enable the intl extension you should use only localized numbers in the input values, it's a default behavior.
This is an old post, but i hope my answer will help anyone encounters this issue.
Instead of disabling intl extension as suggested above, you can use Data Transformers in form type to manually set the default locale to English and that will let the fields to be shown with English digits.
1) Use Data Transformers to interrupt (hook into) the process of showing the field data.
2) Manually set Locale to English.
here is what i've done with dateOfBirth field in the form type:
$builder -> add(
$builder -> create(
'dateOfBirth', DateType::class, array(
'label' => 'Date of Birth',
'widget' => 'single_text',
'required' => false,
'html5' => false,
'attr' => ['class' => 'form-control']
)) -> addModelTransformer(new CallbackTransformer(
function($dateOfBirth) {
\Locale::setDefault('en');
return $dateOfBirth;
},
function($dateOfBirth) {
return $dateOfBirth;
}
))
);

Rounded decimal in edit form Symfony2 + Doctrine2

How do I set the decimal precision and scale within the symfony2 entity? I've defined latitude in longitude fields using decimal data type in my entity like this:
/**
* #ORM\Column(type="decimal", precision="10", scale="6", nullable=true)
*/
protected $latitude;
When persisting new object it saves decimal correctly (I can see 52.406374 in phpMyAdmin). However when displaying edit form the number is rounded to 52,406 and after updating it is stored in mysql as 52.406000. Probably something is wrong with my Doctrine configuration, but I don't know what.
Why is the latitude and longitude getting rounded?
Found a solution:
Symfony's Form component renders decimal form field as type="text". When using:
->add('latitude', 'number', array(
'precision' => 6,
))
It is rendered properly. The thread from comment doesn't describe my problem.
I guess they have already fixed bug with 'convert to float' precision.
When I was displaying latitude in twig template it was showing proper (not rounded) value.
How to set the symfony decimal type precision and scale:
Set it in your entity, like this:
protected $mycolumn;
/**
* #ORM\Column(type="decimal", precision=14, scale=8, nullable=true)
*/
This sets the datatype in the MySQL database:
mycolumn decimal(14,8)
What do scale and precision mean when specifying a decimal field type in Doctrine 2?
Maybe the problem is not due to your doctrine mapping.
Look at this reference documentation for NumberType.
It is what you use? You probably have to change the precision.
In Symfony3.2 you should use scale:
$builder->add('lat', NumberType::class, array('scale' => 8));
This specifies how many decimals will be allowed until the field
rounds the submitted value (via rounding_mode). For example, if scale
is set to 2, a submitted value of 20.123 will be rounded to, for
example, 20.12 (depending on your rounding_mode).

Resources