I have this entity, if I create a record like this.
$synopsis = new Synopsis();
$synopsis->setPartOne("a");
$synopsis->setPartTwo("b");
$synopsis->setTitle("A");
$synopsis->setSubtitle("B");
$synopsis->setEnabled(false);
$em->persist($synopsis);
$em->flush();
And then I go to my Admin, I see the enabled field to "no" which is expected.
But now, If I use the sonata admin new form field, even if I choose enabled "no", the record is created with enabled = true. And I don't really see why it would be like that.
Here is what I have in my SynopsisAdmin
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('title', TextType::class);
$formMapper->add('subtitle', TextType::class);
$formMapper->add('partOne', TextAreaType::class);
$formMapper->add('partTwo', TextAreaType::class);
$formMapper->add('enabled', BooleanType::class);
}
This is how the enabled field is defined in the entity
/**
* #ORM\Column(type="boolean")
*/
private $enabled;
Thanks for your help.
EDIT: Fun facts too, even if I see no in the sonata view list, when I go to the form view, I see yes instead.
I suspect an error within the sonata core functionnality.
I think you should use the CheckboxType instead of the BooleanType for your Form fields.
Looks like the BooleanType is ment for the list, show and grid actions.
https://symfony.com/doc/master/bundles/SonataAdminBundle/reference/field_types.html
Update
To use the BooleanType you have to set the 'transform' option to true.
This transforms your boolean value to the YES/NO options in the BooleanType:
$formMapper
->add('enabled', BooleanType::class, [
'transform' => true
])
Related
I'm sorry for the title but I don't know how to define it good. I'd like my app to sort data (in Doctrine) depending on the sort option which user select it in form dropdown list.
The data I mentioned above are stored inside my Doctrine Entity which I called it Flashcards and the Flashcards Entity contains properties which them must be sorted by option that user select in dropdown. Flashcards Entity looks like the following (I gave only a few properties for simplicity):
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Words", inversedBy="flashcards")
* #ORM\JoinColumn(nullable=false)
*/
private $words;
/**
* #ORM\Column(type="datetimetz")
*/
private $creation_date;
Now the controller's code for form is usual, like the Symfony Doc say:
// code for form inside FlashcardController
$flashcard = new Flashcards();
$form = $this->createForm(FlashcardType::class, $flashcard);
And inside FlashcardController render() method I call createView() method on $form object.
The form code is placed inside FlashcardType class and contains code for mentioned above dropdown list and its options. It looks like this (for simplicity I gave only the methods):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('sortBy', ChoiceType::class, [
'label' => 'Sort by',
'choices' => [
'Date increase' => 1,
'Date decrease' => 2,
'Word alphabetically' => 3,
'Word not alphabetically' => 4
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Flashcards::class
]);
}
So as you see the dropdown options include sorting by: date increase, date decrease, word alphabetically, word not alphabetically. User choose one of them in view. So manipulating data by user does NOT change value of this data represented by properties. Changing sort option in dropdown should change Doctrine query to sort by user-changed value. I have no idea how to achieve this in Symfony. Could you give me plese some tips how to make it?
Thank you in advance for answers!
If I understood correctly you have a few options:
First: wire javascript / jquery to select input and submit the form when user changes order(it should reload the form applying the filter, you can set any data user used in the 'previous' page using RequestStack to get the form fields from request / query depending on the method)
Second: get all the nodes you display record and try to manipulate the order based on the select value every time user changes the value
Tell me if this is what you meant else correct me and I'll try to provide the answer
I have a form in Symfony2 which I am building with buildForm
I add constraints like so,
$builder
->add('firstName', 'text', [
'required' => true,
'constraints' => [
new NotBlank(),
],
]
)
Everything works fine until I delete the input from my html and submit it without the firstName. I don't get any errors and it submits normally. Is there a way to absolutely require the firstName, even if is not present in the submit data
You must use an assert with your entity as explained in the symfony documentation here
like this:
class User
{
/**
* #orm:Column(type="string", nullable=false)
* #assert:NotBlank
*/
private $firstname;
}
You did not submit any data, the form is not submitted hence no validation is triggered.
Instead of:
$this->handleRequest($request);
Try to always submit the form even if the data is missing:
$form->submit($request->request->all());
I cannot guarantee this code is valid in your context since you did not provide your controller code.
I have two (2) Admins, UserAdmin and CarAdmin. From the list view of UserAdmin, I want to have a custom action that redirects to CarAdmin create view with the user already selected.
So far I have managed to create a custom action with its controller. My challenge is to redirect to CarAdmin create/new form passing some parameters for data persistence.
Any points of reference will be much appreciated.
Thanks
Sonata Admin allows to resolve such task pretty easy, no need to make a custom action. One of the solutions could be:
Define a custom template for one column in UserAdmin list view, render a special button(link) in it. A link should lead to CarAdmin create action with some get parameter.
In CarAdmin in method getNewInstance() check that if there is a special get parameter - set user with that ID. This step can also be done in methods getFormFields(), prePersist(), etc.
Some code samples:
In UserAdmin
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->add('actions', 'string', array(
'template' => 'your_template_name.html.twig',
'mapped' => false,
)
);
}
In your_template_name.html.twig
Create Car for this user
In CarAdmin
public function getNewInstance()
{
$car= parent::getNewInstance();
$userId = $this->getRequest()->query->get('user');
if ($userId) {
$em = $this->modelManager->getEntityManager(User::class);
$user = $em->getRepository(User::class)->find($id);
$car->setUser($user);
}
return $car;
}
I work with symfony 2.8 and FOSUserBundle, I have two type of user in the same table in database , And I like to differenciate the registration form in the same page of registration like this :
*
the problem that I can't use two instance of the form in the same page, what can I do please?
The way I would go about this, is override FOSUserBundle and then extend the RegistrationController and likely the corresponding template.
In the registerAction you can reuse some parts of the original, but where the form is created you then create two different ones, maybe like this:
/** #var $formFactory FactoryInterface */
$clientFormFactory = $this->get('client_registration.form.factory');
$clientForm = $clientFormFactory->createForm();
$clientForm->setData($client);
/** #var $formFactory FactoryInterface */
$correspondentFormFactory = $this->get('correspondent_registration.form.factory');
$correspondentForm = $correspondentFormFactory->createForm();
$correspondentForm->setData($correspondent);
$clientForm->handleRequest($request);
$correspondentForm->handleRequest($request);
if ($clientForm->isSubmitted() && $clientForm->isValid()) {
// ...
} elseif ($correspondentForm->isSubmitted() && $correspondentForm->isValid()) {
// ...
}
return $this->render(
'#FOSUser/Registration/register.html.twig',
[
'clientForm' => $clientForm->createView(),
'correspondentForm' => $correspondentForm->createView(),
]
);
The part inside the if conditions will then probably look similar as to the original controller. You might have different UserManager's for each user type, you have to switch out, but other than that it's basically: dispatch pre-event, save user, dispatch post-event, redirect. It is important that you dispatch both events as other parts of FOSUserBundle will rely on them, e.g. sending a registration email.
In your template you then just render both forms in their tab. You might have to fiddle around with the form id's a bit, but that should be straightforward.
There is SonataAdminBundle and User entity. Admin service for it:
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('name')
// ...
->add('send_greeting', 'checkbox')
;
}
Field send_greeting is not related to User entity. It required only for admin service (depends it value we would send email or not after saving user). So how it possible add this field to form without binding to entity?
With symfony 2.1 and above, use mapped instead of property_path. (Symfony2 form reference)
You can set property_path option to false. e.g
->add('send_greeting', 'checkbox',array(
'property_path' => false
))
...