im developing an user profile section for my app. I have a password field to allow the user change your password.
I have a problem with this. When the user fill the password input, your password are updated correctlly. But when, the user not fill the input, the user password set a blank value.
I like if that user not fill the input, keep the current password.
It is my form definition:
$builder
->add('email','text',array(
'required' => false
))
->add('clave','password', array(
'required' => false,
'always_empty' => true
))
->add('reClave','password',array(
'mapped' => false,
'required' => false
))
->add('telefonos','collection', array(
'type' => new TelefonoType(),
'required' => false,
'allow_add' => true,
'allow_delete' => true
))
->add('submit', 'submit')
->add('reset', 'reset')
;
Note: I dont use FOSUserBundle.
Any ideas ?
Like #Tejas suggested you, you can check in your User::setPassword() function if your param is empty and set it only if it's not. But it's not the best way because you override a form constraint in your entity (the NotBlank constraint on a password).
A better and simple solution would be to display two separated forms on your profile edition page. First for common data, and second for password update. Then you can a NotBlank constraint on your field, make it repeated type (doc here) if it's not, also add more constraints like "more than 6 characters" (Range) or "at least letters and numbers" (Regex).
The last solution is to use Form Events to control your validation rules according to your form : creation or edition. But it is more complecated to manipulate.
Related
I have a little problem I don't understand.
I want to display my errors in the same location at the top of the form, I used form_errors(form)
Then in my form, I added a default value to my fields.
$resolver->setDefaults([
'data_class' => Whitelist::class,
'error_bubbling' => true
]);
Currently, it does not work and my errors appear in their respective fields.
But if I put this option 'error_bubbling' => true to my field, it works. Why by default it does not work?
->add('firstName', null, [
'label' => "Prénom de votre personnage",
'error_bubbling' => true
])
Sorry for my english, thanks.
'error_bubbling' => true means that the error will "bubble" up to the form, where you are trying to display it.
From the docs:
error_bubbling
type: boolean default: false unless the form is compound
If true, any errors for this field will be passed to the parent field or form. For example, if set to true on a normal field, any errors for that field will be attached to the main form, not to the specific field.
I'm building a form which has an EntityType element, the problem I have is that I'm unable to have the placeholder translated.
Here is my code:
$builder
->add('Products', EntityType::class, [
'mapped' => false,
'expanded' => true,
'multiple' => false,
'required' => false,
'class' => Product::class,
'choices' => $options['step']->getProducts(),
'placeholder' => 'form.mat.alreadyOwned',
'label' => 'form.mat.alreadyOwned',
'translation_domain' => 'messages'
])
When I use the form.mat.alreadyOwnedtranslation as the label it works fine, but I would like to use it in the placeholder instead. What am I missing?
Looking forward to any tips or tricks that you have to offer!
[UPDATE]
As pointed out by #gp_sflover I'm not trying to replace the general placeholder, but the one for the empty value. This one only appears if you set required to false.
After some research and thought, the places where the placeholder is actually used are quite limited in number (as it should be). However, specific placeholder translation is not a special case (sadly).
For every choice in a ChoiceType a ChoiceView is added. Also for the placeholder a ChoiceView is added, that inherits the options of the form (which is a somewhat sensible choice for the ChoiceType), including the translation_domain parameter, which indicates that the choices shall be translated (all of them). There's also a reference in some twig template that specifically manages the translation in the twig bridge for non-expanded choice types. However, those don't open up a specific best practices answer on how to specifically handle translations for the placeholder in the ChoiceType.
For the EntityType, this doesn't change.
So there are a few approaches, some of which might be absolutely utility-free ...
translate the placeholder right there when building the form
Although this is conceptually not the most beautiful option, IMHO it's still the most practical one. Essentially, in Symfony 4 forms can receive dependencies in their constructor via auto-wiring, so injecting a TranslatorInterface will open up the ability to translate the placeholder with the requests locale (which is automatically set for the translator via event listener):
public function __construct(TranslatorInterface $translator) {
$this->translator = $translator;
}
and in your buildForm you can then use it to translate the placeholder
$builder
->add('Products', EntityType::class, [
'mapped' => false,
'expanded' => true,
'multiple' => false,
'required' => false,
'class' => Product::class,
'choices' => $options['step']->getProducts(),
'placeholder' => $this->translator->trans('form.mat.alreadyOwned'), // <-- change
'label' => 'form.mat.alreadyOwned',
'translation_domain' => 'messages'
])
not to withhold the other options, which in my opinion are almost all overkill...
set a choice_translation_domain for all entries, including placeholder
obviously, this can and probably will lead to problems, if there ever is an entity that whose choice label matches the key in the translator ... and it is not intended for translation. but it will translate the placeholder with the very same translation_domain ...
adapt the form rendering and check for the placeholder
this is problematic, since you have to assign the form theme/form rendering to all relevant forms. the placeholder does have a unique name ('placeholder', who would have thought) so it could very well be used to achieve that goal. However, setting a different translation domain could very much be challenging. (if you attempt this, it's a bit of a nuisance)
write your own entity type (optionally adding own form rendering)
theoretically, you could create your own EntityType and handle the placeholder properly there. like ... adding a translation domain to the choice view and sub form and what not. For inspiration/reference consult the ChoiceType, EntityType and DoctrineType (parent type).
This page actually a preview where user can't change anything,that he has given before.I have tried bellow code,
echo $this->Form->input('exchange_type', array(
'disabled' => 'disabled',
'empty' => '--Please Select--',
'options' => array(
'6' => 'POINT_TO_PRODUCT',
'7' => 'POINT_TO_GIFT',
'2' => 'POINT_TO_GAME'
)
));
Here field has disabled but it's sending null value to database.I am trying to send actual value that user has been selected.How can I do this ?
That's how HTML works, values of disabled elements are not being sent.
What you can do is using a hidden field, that's what the form helper automatically does when using for example checkboxes, in order to ensure that there's always a value being sent, as unchecked checkboxes do not submit any value, just like disabled inputs.
The hidden field should have the same name as the actual field, and it should be placed before the actual field, that way the hidden value will only be sent in case the following element is disabled.
echo $this->Form->hidden('exchange_type');
echo $this->Form->input('exchange_type', array(
'disabled' => true,
// ...
));
That would pick up the previously POSTed value for both the hidden input and the select input, and the hidden input would be submittable.
See also Cookbook > Helpers > FormHelper > FormHelper::hidden()
I have a form with an collection:
$builder->add('languages', 'collection', array(
'type' => new LanguageType(),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false
));
In the twig-template I render an additional row with an empty (LanguageType). For that I use the prototype and replace the name.
In the Controller I bind the Request and discard the "empty" Language in the setter:
public function addLanguage($lang)
{
if($lang->getLanguage())
{
$this->languages->add($lang);
}
// discard the others
}
For some Reason the "empty" row throws an validation error via the NotBlank validator.
My only working solution is to remove the empty row from the raw-Request but thats ugly.
Your solution is valid.
Otherwise you could set the option required to false on $builder->add('lang') but then you would have to do some extra checking yourself.
$builder->add('lang', 'text', array(
'required' => false
));
Documentation about the required option.
Or you can create some JS code that injects the name of the input only when the field is not empty (input with an empty name doesn't have its value sent through). It isn't great either but it works.
I am using Symfony 2.1.8 and I have form with an entity which has many-to-one relation on it.
I use entity field for this member and i call it in the buildForm() as:
$builder->add('direction', 'entity', array(
'class' => 'CompanyBundle:Direction',
'property' => 'enTranslation.arrowedTitle',
'empty_value' => false,
'label' => 'Connection Direction',
'required' => false
));
enTranslation.arrowedTitle is a function that returns a string which including '⇒' (character set for right arrow)
when i call {{ form_widget(form.direction) }} i see the string as it is,(not the arrow but the &rArr) For displaying purposes, arrows must be showed, but i see &rArr in the field.
For simple string rendering, |rawfilter is used, but it does not work on widget. What should I do in order to display ⇒ instead of '&rArr ;' in the form? Thanks for any help.
You will have to create a form theme for at minimum the field type who's label includes that character.
Symfony/Twig escapes values by default for safety.
See this section of the documentation for more info:
http://symfony.com/doc/current/cookbook/form/form_customization.html#form-theming