Symfony4 - change single parameter in url after submitting form - symfony

I have a route that looks like this - route/{parameter} and I need to change the parameter after submitting a form.
I tried to use redirectToRoute but it created new URL together with some other parameters that the form passed which I don't want.
So I would love to ask you if there is some way to redirect to a new URL with the only parameter that I choose through select in the form.
Thank you very much for your responses.
EDIT:
I am going to share more actual information. This is how my controller for the form looks like:
$form = $this->createFormBuilder()
->setMethod("get")
->add('category', ChoiceType::class, [
'choices' => [
'Všechny kategorie' => 'vsechny-kategorie',
'Automobilový průmysl' => 'automobilovy-prumysl',
'Stavebnictví' => 'stavebnictvi',
'Elektronika a elektrotechnika' => 'elektronika-a-elektrotechnika',
'Gastronomie' => 'gastronomie',
'Lesnictví' => 'lesnictvi',
'Potravinářský průmysl' => 'potravinarsky-prumysl',
'IT technologie' => 'it-technologie',
'Logistika' => 'logistika',
'Strojírenství' => 'strojirenstvi',
'Zdravotnictví' => 'zdravotnictvi'
],
'label' => 'Kategorie:'
])
->add('send', SubmitType::class, ['label' => 'Test'])
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$category = $data['category'];
return $this->redirectToRoute('jobs', [
'jobs' => $pagination,
'categoryForm' => $form->createView(),
'category' => $category,
]);
}

You should be able to use the redirectToRoute, but be sure to pass the parameter you're trying to dynamically set as an array:
// in your controller action:
return $this->redirectToRoute('post_form_route', ['parameter' => $parameter]);
If that's not working for you, I would double check your route definitions and make sure your route's name & expected URL parameters are passed correctly.
Documentation on redirecting in the controller

you can try that :
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$category = $data['category'];
return $this->redirectToRoute('route', [
'parameter' => $form->getData()->getCategory()
]);
}
return $this->redirectToRoute('jobs', [
'jobs' => $pagination,
'categoryForm' => $form->createView(),
]);

Related

Rendering a template with form inside from a service

my DataTable service code is given below
public function dataTableTest(string $class, Request $request, $FormBuilder): Response
{
$FormFactory = Forms::createFormFactory();
$form = $FormFactory
//->createBuilder()
->create('App\Form\NewsType', null, array(
'method' => 'POST',
))
->add('task', TextType::class, [
'label' => 'Some task',
'required' => true,
])
->add('dueDate', DateType::class)
->add('save', SubmitType::class, [
'label' => 'Create',
])
//->getForm()
;
$response = $this->twig->render('forms/FormFactory.html.twig', [
'controller_name' => 'FormsController',
'form' => $form->createView(),
]);
return new Response($response);
}
FormFactory.html.twig code is
{{ form(form) }}
and i have an error
SyntaxError HTTP 500 Internal Server Error
Unknown "form" function.
1 so how can render a template with twig function 'form' ? or its not possible?
2 When i render some template from service than
a)twig knows entity functions or properties like 'array.id'
b)twig does not know all twig functions like form(), form_start
and so on.
c) I think i need some extra twig dependency injections

Symfony3 :: Handle ManyToMany relations

I'm trying to save my ManyToMany relations between users and categories. Actually I'm trying to save my category with given users, but this doesn't work.
Form
$builder->add('name')
->add('users', EntityType::class, array(
'label' => 'Benutzer',
'class' => 'AppBundle\Entity\User',
'multiple' => true,
'expanded' => true,
'required' => false,
'choice_label' => function (User $user) {
return $user->getUsername();
}
))
->add('submit', SubmitType::class, array(
'label' => 'Speichern'
));
Form Handler
public function onSuccess(Request $request)
{
// Get category from form
$category = $this->getForm()->getData();
// Redirect to parent category when setted
if ($this->parent) {
$category->setParent($this->parent);
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $this->parent->getId()
]));
} else {
// Build new redirect response
$response = new RedirectResponse($this->router->generate('categories.view', [
'category' => $category->getId()
]));
}
try {
// Save category in database
$this->em->merge($category);
$this->em->flush();
} catch (ORMException $ex) {
throw $ex;
}
return $response;
}
Maybe you have to unserialize the Entity $category first?
$detachedCategory = unserialize($category);
$this->em->merge($detachedCategory);
$this->em->flush();
I found this link regarding that:
How to manage deserialized entities with entity manager?
Not sure if that's the answer, but you might want to do more research.

Symfony 3: How to use two choices/dropdowns from two tables in one form

Symfony version 3.1.3
I have created a dropdown using the entity called Classes and you can see the Controller below,
public function studentAddClassAction( $id, Request $request )
{
// get the student from the student table
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('PIE10Bundle:Users')->find($id);
// new class object and create the form
$classes= $em->getRepository('PIE10Bundle:Classes')->findAll();
$form = $this->createForm(ClassType::class, $classes);
$form->handleRequest($request);
if( $form->isSubmitted() && $form->isValid() )
{
// form submit operations
}
return $this->render(
'PIE10Bundle:student:layout_student_addclass.html.twig',
array(
'user' => $user,
'title' => 'Add Class',
'tables'=> 1,
'form' => $form->createView()
)
);
}
and the ClassType is below
class ClassType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('classes',
EntityType::class,
array('class' => 'PIE10Bundle:Classes',
'expanded' => false,
'multiple' => false,));
$builder->add('Add Class',
SubmitType::class,
array('attr' => array('class' => 'btn btn-primary',
'style' => 'margin:15px 0;')) );
}
}
And this works fine and it gives all the classes from the database. Also I have another entity called Users and it has a column called roles (DC2Type:array) and it has a role called ROLE_PARENT and I can retrieve all the parents using the following query
$query = $this->getDoctrine()->getEntityManager()
->createQuery('SELECT u FROM PIE10Bundle:Users u WHERE u.roles LIKE :role')
->setParameter('role', '%"ROLE_PARENT"%' );
$users = $query->getResult();
My Question is how to add these parents list as a choice list into same above form in the studentAddClassAction Controller.
Please let me know in any other information is needed for this.
To have a custom set of entities as a choice list you need to use a query_builder option
So it will look like
$builder->add('parent',
EntityType::class,
array('class' => 'PIE10Bundle:Users',
'expanded' => false,
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->where('u.roles LIKE :role')
->setParameter('role', '%"ROLE_PARENT"%');
},
'multiple' => false
));

Symfony - Form redirect

I am building simple car renting app in Symfony for a programming class at my university.
On URL /search I show a form to user. Right now when the form is submitted user his /search again but different template is rendered
This is form code:
class SearchQueryType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('pickupCity', TextType::class)
->add('returnCity', TextType::class)
->add('pickupDateTime', DateTimeType::class, array(
'years' => range(2016,2017),
'error_bubbling' => true,
))
->add('returnDateTime', DateTimeType::class, array(
'years' => range(2016,2017),
'error_bubbling' => true,
))
->add('save', SubmitType::class, array(
'label' => 'Find Car',
'attr' => array(
'class' => 'btn-secondary btn-lg'
)))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\SearchQuery',
));
}
}
And controller for this route:
class SearchController extends Controller
{
public function searchAction(Request $request)
{
$query = new SearchQuery();
$form = $this->createForm(SearchQueryType::class, $query);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/* Some logic here */
return $this->render('AppBundle:default:results.html.twig', array(
'form' => $form->createView()
));
}
return $this->render('AppBundle:default:search.html.twig', array(
'form' => $form->createView()
));
}
}
However when the form is submitted I want to redirect to URL /results?SUBMITTED-PARMS-HERE, so user can send this link to someone and receive the same results. On /results again I wand to render form, this time filled with search params submitted and below render available car.
I don't know if its the best way to handle this problem, current solution works but link can't be send to someone else.
EDIT:
I change the code to fallowing:
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$session = $this->get('session');
$session->set('pickupCity', $data->getPickupCity());
$session->set('returnCity', $data->getReturnCity());
$session->set('pickupDateTime', $data->getPickupDateTime());
$session->set('returnDateTime', $data->getReturnDateTime());
return $this->redirectToRoute('results', array(
'pickupCity' => $data->getPickupCity(),
'returnCity' => $data->getReturnCity(),
'pickupDate' => $data->getPickupDateTime()->format('d-m-Y-H-i'),
'returnDate' => $data->getReturnDateTime()->format('d-m-Y-H-i'),
), 301);
}
So as a result I receive URL ./results/Paris/Berlin/10-02-2016-10-00/17-02-2016-10-00
And in routing.yml:
results:
path: /results/{pickupCity}/{returnCity}/{pickupDate}/{returnDate}
defaults: { _controller: AppBundle:Search:result}
methods: [POST]
Because I only want to receive POST request on this route and now when I submit form I get error page saying:
No route found for "GET /results/Paris/Berling/01-07-2016-00-00/01-11-2016-00-00": Method Not Allowed (Allow: POST)
Any idea how to fix it?
EDIT 2:
Never mind, my reasoning was bad.
Not sure, but maybe using this example.
$this->redirect($this->generateUrl('default', array('pickupCity' => $pickupCity, 'returnCity' => $returnCity, 'pickupDateTime' => $pickupDateTimepickupDateTime)));
With your own parameter, which you can get where you put your comment
/* Some logic here */
You can use getQueryString() function.
Sample:
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirect('results?'.$request->getQueryString());
}

Symfony 2: Set field as read only after first save

I have a Symfony 2 entity. When I create a new record, I must fill all the values using a form, but after saving it, one of the values, $amount shouldn't be updatable when I update the others members.
How can I accomplish this? It's possible to mark a form member as a read-only, in runtime?
By using the validation_groups and name options when creating your form, you can change the form.
The name attribute sets the form creation, and the validation_groups takes care of the validation.
For example, in the create/new method of your controller;
public function createAction(Request $request)
{
// Instantiate new Foo object
$client = new Foo();
// create the form (setting validation group)
$form = $this->formFactory->create('foo', $foo, array(
'name' => 'create',
'validation_groups' => array('create')
)
);
// form has been submitted...
if ('POST' === $request->getMethod()) {
// submits the form
$form->handleRequest($request);
// do validation
if ($form->isValid()) {
// do whatever
}
}
// either GET or validation failed, so show the form
return $this->template->renderResponse('FooBundle:foo:add.html.twig', array(
'form' => $form->createView(),
'foo' => $foo
));
}
And in the edit/update function of your controller;
public function updateAction($id, Request $request)
{
// Instantiate Client object
$client = new Foo($id);
// create the form (setting validation group)
$form = $this->formFactory->create('foo', $foo, array(
'name' => 'update',
'validation_groups' => array('update')
));
// form has been submitted...
if ('POST' === $request->getMethod()) {
// submits the form
$form->handleRequest($request);
// do validation
if ($form->isValid()) {
// do whatever
}
}
// either GET or validation failed, so show the form
return $this->template->renderResponse('FooBundle:foo/edit:index.html.twig', array(
'form' => $form->createView(),
'foo' => $foo
));
}
And your Form Type will look something like;
class FooType extends BaseAbstractType
{
protected $options = array(
'data_class' => 'FooBundle\Model\Foo',
'name' => 'foo',
);
private $roleManager;
public function __construct($mergeOptions = null)
{
parent::__construct($mergeOptions);
}
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$this->$options['name']($builder, $options);
}
private function create(FormBuilderInterface $builder, array $options)
{
// ID
$builder->add('Id', 'text', array(
'required' => true,
'label' => 'ID',
'attr' => array(
'placeholder' => 'Format: 2 alphanumeric (e.g. A1)'
)
));
// Name - only show on create
$builder->add('Name', 'text', array(
'required' => true,
'label' => 'Name',
'attr' => array(
'placeholder' => 'Your name'
)
));
// add the submit form button
$builder->add('save', 'submit', array(
'label' => 'Save'
));
}
private function update(FormBuilderInterface $builder, array $options)
{
// ID
$builder->add('Id', 'text', array(
'required' => true,
'label' => 'ID',
'attr' => array(
'placeholder' => 'Format: 2 alphanumeric (e.g. A1)',
)
));
// Name - just for show
$builder->add('Name', 'text', array(
'required' => true,
'label' => 'Name',
'attr' => array(
'readonly' => 'true' // stops it being editable
)
));
// add the submit form button
$builder->add('save', 'submit', array(
'label' => 'Save'
));
}
}
P.S. All my classes are declared as services, so how you call create forms/views/etc may be different.

Resources