I have a form which has a form (CustomerVatsType) for an entity (CustomerVats). This entity has a column (vats), which contains multiple vat rows. These rows are saved in json format. On this form, customer can choose a default vat, which will be saved in "default" index of rows saved in units column.
but problem is that radio input name is "form[vats][0][set_default]" due to structure of form. But for radio input to work correctly it needs to be same for all inputs (e.g. form[vats][set_default]). I can change name in twig file but then form class can not understand this.
What can be done for this situation. Does even Symfony support it. Here is my form class.
class VatsType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('vats', CollectionType::class, array(
'entry_type' => VatType::class,
'allow_add' => false,
'allow_delete' => false,
'prototype' => false,
'by_reference' => false,
)
)
->add('vatSumbit', SubmitType::class);
}
}
class VatType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
$builder
->add('country_id', HiddenType::class, array('label' => false))
->add('vat_high', HiddenType::class, array('label' => false))
->add('vat_low', HiddenType::class, array('label' => false))
->add('vat_zero', HiddenType::class, array('label' => false))
->add('vat_none', HiddenType::class, array('label' => false))
->add('set_default', RadioType::class, array('label' => false))
->add('set_show', RadioType::class, array('label' => false));
}
}
I ended up using following fix for this problem. It seems bit dirty but made most sense to because I dont want to confuse other devs with some really difficult method.
<script type="text/javascript">
(function (document, window, $) {
$('[data-radio-field]').change(function () {
var field = $(this).data('radio-field');
$('[data-radio-field="' + field + '"]').not($(this)).prop('checked', false);
});
})(document, window, jQuery);
</script>
If anyone can suggest a clean method, they are welcome to answer it. I think it should be a common problem. Would like to see other approaches well.
Related
I can not get value from EntityType. I have last version 3.3.6.
class BuildType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('title', TextType::class)
->add('save', SubmitType::class, array('label' => 'Create Post'))
->add('team', CollectionType::class, array(
// each entry in the array will be an "email" field
'entry_type' => TeamType::class,
// these options are passed to each "email" type
'entry_options' => array(
'attr' => array('class' => 'form-control'),
),
'label' => false,
'allow_add' => true,
'prototype' => true,
'mapped' => false
));
}
}
class TeamType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array
$options)
{
$builder
->add('name', EntityType::class, array(
'placeholder' => 'Choice a champ',
'required' => true,
'class' => 'AppBundle:Champions',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
},
'choice_label' => 'name',
'choice_value' => 'id',
'attr' => array('class' => 'dropdown'),
));
}
I tried all but i cannot take value of 'name' of TeamType. After submission form, i do
foreach ($form["team"]->getData() as $value) {
'name' => $value['name']
but the value is empty. If i try dump request and the value is there. The other values i can get it and save in Database. Only EntityType i can not.
Someone know how do?
EntityType returns as the object. You should use model getter functions.
$form->get('name')->getData()->getId(); // getName() vs..
Here is a similar example.
symfony how get selected data from select
I suppose that you are using ManyToOne relationship.
With AJAX
if you are trying get data after submitted, You can do this first in your view:
$('#elementWhereYouAreTEAMType').find('input').each(function (i,v) {
var valTeam = $(this).val(); //take value
// adding data, create an associative array.
formData.append("team["+ i +"]", valTeam);
});
You must put formData like data argument to ajax JQuery
Now, server side:
public function createTeamNow(Request $request) {// ajax
$teams = $request->request->get('team'); // getting array
if(!is_null($teams)) {// if user added team
foreach ($teams as $team) {
// dump($team);
//create an instance for each element, it does not replace a data with the above
$teamType = new TeamType();
$teamName->setName($team);
$this->em->persist($teamType);
}
}
}
Without AJAX
/**
* #Route("/slim/1" , name="data_x")
*/
public function slimExampleAction(Request $request)
{
$form = $this->createForm(TeamType::class);
$form->handleRequest($request);
if ($form->isSubmitted() /*&& $form->isValid()*/) {
// When you've ManyToOne relationship, that field returns ArrayCollection class, it has several method to get data on differents ways, iterate with it, for example toArray is one
$data = $form->getData();
dump($data->getDescription()->toArray());die;
}
return $this->render('AppBundle:view.html.twig', array(
'form' => $form->createView(),
));
}
I'm looking for best (or just working) way to solve following problem.
I have like standard UserType form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'username',
Type\TextType::class
)
->add(
'email',
Type\EmailType::class
)
->add(
'plainPassword',
Security\UserRepeatedPasswordType::class
)
->add(
'roles',
Type\ChoiceType::class,
[
'multiple' => true,
'expanded' => true,
'choices' => $this->getRoleChoices()
]
);
}
What is nonstandard is that UserRepeatedPasswordType, it looks like this
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'password',
Type\RepeatedType::class,
[
'type' => Type\PasswordType::class,
'required' => true,
'first_options' => [
'label' => 'Password'
],
'second_options' => [
'label' => 'Repeat Password'
],
]
);
}
And I created it because those two fields are also used in passwordReset form and userSettings form. And now I have two problems:
1.) When I use it this way, value from UserRepeatedPasswordType is not correctly mapped for my User Entity - there is an error that string is expected (duh ;) but it got array. I tried using View and Model transformer but no proper results (but I don't have much experience with those, so that maybe the case). I also tried to experiment with getParent(), and pass there UserType but it goes to some endless loop and I got 500. If I just copy paste field from UserRepeatedPasswordType to UserType it works correctly.
2.) If this is solved (or even by copy paste, if can't be done other way), there is another related (I believe) problem:
I have this ChangePasswordType form, which is used to reset your password.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add(
'confirmationToken',
Type\HiddenType::class,
[
'required' => true,
'constraints' => [
new NotBlank(),
]
]
)
->add(
'plainPassword',
Type\RepeatedType::class,
[
'type' => Type\PasswordType::class,
'required' => true,
'first_options' => [
'label' => 'Password'
],
'second_options' => [
'label' => 'Repeat Password'
],
]
)
->add(
'changePassword',
Type\SubmitType::class
);
}
And it works fine as it is but I want to do two things with it - first, solving my first problem and use UserRepeatedPasswordType in it, second - I have some Assert\Length done in User Entity on $plainPassword and it workes correctly when I submit new user via UserType form. But I want that validation somewhat mapped to ChangePasswordType or ideally to UserRepeatedPasswordType - just to have all rules in one place. Can this even be done? Thanks for any solutions / hints / advices.
Ok, dunno if anyone is interested but that is how I completed this. If anyone have better answer, just give me a sign (mostly to the first one) ;)
1.) As i thought, solved by ViewTransformer but in parent form (In UserType not in UserRepeatedPasswordType
$builder->get('plainPassword')
->addViewTransformer(new CallbackTransformer(
function ($singleAsArray) {
return $singleAsArray;
},
function ($arrayAsSingle) {
return $arrayAsSingle['password'] ?? '';
}
));
2.) That was actually quite easy. All you have to do is to map that form to UserEntity that same way as UserType and made custom validation groups just to have everything nice and under control :)
I'm having dificulties trying to set on my form the selected values on the preferred choices.
I have a class calendar that can have multiple taxes:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('possibledigits')
->add('notes')
->add('autogenerateyear', 'checkbox', array('required' => false))
->add('calendartaxes', null, array(
'required' => false,
'multiple' => true,
'expanded' => true
))
;
}
The relation is many to many:
/**
* #ORM\ManyToMany(targetEntity="CalendarTax", indexBy="name", inversedBy="calendarios")
* #ORM\JoinTable(name="contable_schedule_taxes_relation")
*/
private $calendartaxes;
What I was going to do is to try to get the entity of the form and try to get the selected taxes. But I don't know if that is the correct way to do it.
Is there a more elegant way to do it?
I'm using symfony 2.3.
Regards.
I am assuming you have a relationship set up betwween Calendarios and CalendarTax
so before you create the form ... do
$calendarios = new CalendarIOS();
$calendartax = $this->getDoctrine()->getManager()->getRepository('NamBundle:CalendarTax')->find($calendar_tax_id);
$calendarios->addCalendarTax($calendartax);
now when you send the entity over to the formbuilder...you will have that perticular calendartax checked... :)
Finally I use the preferred_choices of the choice.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$calendario = $builder->getData();
$taxesId = array();
foreach($calendario->getCalendartaxes() as $tax){
$taxesId[] = $tax;
}
$builder
->add('name')
->add('possibledigits')
->add('notes')
->add('autogenerateyear', 'checkbox', array('required' => false))
->add('calendartaxes', null, array(
'required' => false,
'multiple' => true,
'expanded' => true,
'preferred_choices' => $taxesId,
))
;
}
Making one more query and getting the calendar of the form builder.
The comment given by #Hakim was the one that put me on the right path.
Thanks!
I want from the user to select a type of questionnaire, so I set a select that contains questionnaires types.
Types are loaded from a an entity QuestionType .
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'))
->add('type', 'hidden')
;
What am not able to achieve is to set a default value to the resulted select.
I have googled a lot but I got only preferred_choice solution which works only with arrays
I made it by setting a type in the newAction of my Controller I will get the seted type as default value.
public function newAction($id)
{
$entity = new RankingQuestion();
//getting values form database
$em = $this->getDoctrine()->getManager();
$type = $em->getRepository('QuizmooQuestionnaireBundle:QuestionType')->findBy(array('name'=>'Ranking Question'));
$entity->setQuestionType($type); // <- default value is set here
// Now in this form the default value for the select input will be 'Ranking Question'
$form = $this->createForm(new RankingQuestionType(), $entity);
return $this->render('QuizmooQuestionnaireBundle:RankingQuestion:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'id_questionnaire' =>$id
));
}
You can use data attribute if you have a constant default value (http://symfony.com/doc/current/reference/forms/types/form.html)
but it wont be helpful if you are using the form to edit the entity ( not to create a new one )
If you are using the entity results to create a select menu then you can use preferred_choices.
The preferred choice(s) will be rendered at the top of the list as it says on the docs and so the first will technically be the default providing you don't add an empty value.
class MyFormType extends AbstractType{
public function __construct($foo){
$this->foo = $foo;
}
$builder
->add('questionType', 'entity', array(
'class' => 'QuizmooQuestionnaireBundle:QuestionType',
'property' => 'questionTypeName',
'multiple' => false,
'label' => 'Question Type'
'data' => $this->foo))
->add('type', 'hidden')
;
}
In controller
$this->createForm(new MyFormType($foo));
The accepted answer of setting in the model beforehand is a good one. However, I had a situation where I needed a default value for a certain field of each object in a collection type. The collection has the allow_add and allow_remove options enabled, so I can't pre-instantiate the values in the collection because I don't know how many objects the client will request. So I used the empty_data option with the primary key of the desired default object, like so:
class MyChildType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('optionalField', 'entity', array(
'class' => 'MyBundle:MyEntity',
// Symfony appears to convert this ID into the entity correctly!
'empty_data' => MyEntity::DEFAULT_ID,
'required' => false,
));
}
}
class MyParentType
extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('children', 'collection', array(
'type' => new MyChildType(),
'allow_add' => true
'allow_delete' => true,
'prototype' => true, // client can add as many as it wants
));
}
}
Set a default value on the member variable inside your entity (QuestionType), e.g.
/**
* default the numOfCourses to 10
*
* #var integer
*/
private $numCourses = 10;
I've got form class where I'm defining some inputs, something liek this:
class User extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('mail', 'text', array('label' => 'Mail'))
->add('password', 'text', array('label' => 'Hasło'))
->add('description', 'textarea', array('label' => 'Opis'));
}
}
I want to change mail and password input type to readonly and set them some values.
Now, I use form this way:
$form = $this->createForm(new User($this->get('database_connection')));
I tried many things, but Symfony2 has so many Form classes and I've lost in that.
I want to simply add some atributes to existing, added inputs.
I don't use Doctrine2 ORM, I use Doctrine DBAL, if it does matter.
Thanks in advance.
your can set default value with 'data' parameter and readonly with attr parameter
$builder
->add('mail', 'text', array('label' => 'Mail', 'data' => 'Default value'
attr => array('readonly=>'readonly')));