I have an entity Playlist that is related to another call Items.
I want to deploy on a twig template id of each of the items.
class Playlist
{
private $items;
public function __construct()
{
$this->items = new \Doctrine\Common\Collections\ArrayCollection();
}
public function addItem(\Publicartel\AppBundle\Entity\PlaylistContent $content)
{
$content->setPlaylist($this);
$this->duration += $content->getDuration();
$this->items->add($content);
return $this;
}
public function removeItem(\Publicartel\AppBundle\Entity\PlaylistContent $content)
{
$this->items->removeElement($content);
$this->duration -= $content->getDuration();
}
public function getItems()
{
return $this->items;
}
}
I want to deploy in the Playlist form the id of the item.
I've tried like so:
{% for content in edit_form.items %}
{{ content.getId() }}
{{ content.id() }}
{% endfor %}
But I get the following error:
Method "getId" for object "Symfony\Component\Form\FormView" does not
exist Method "id" for object "Symfony\Component\Form\FormView" does
not exist
I've added the id attribute to my FormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id')
->add('position')
->add('duration')
->add('playlist')
->add('content')
;
}
But I get the following error:
An exception has been thrown during the rendering of a template
("Catchable Fatal Error: Object of class
Symfony\Component\Form\FormView could not be converted to string")
I've also tried:
// Controller
$entity = $em->getRepository('PublicartelAppBundle:Playlist')->find($id);
return $this->render('PublicartelAppBundle:Playlist:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
// Twig
{{ entity.items.id }}
But that too throws an error:
Method "id" for object "Doctrine\ORM\PersistentCollection" does not exist
Thanks!
Solution 1
Last part of your solution is the good one
$entity = $em->getRepository('PublicartelAppBundle:Playlist')->find($id);
return $this->render('PublicartelAppBundle:Playlist:edit.html.twig', array(
'entity' => $entity,
[...]
));
What isn't good is that snippet of code
{{ entity.items.id }}
You have to cycle over all items before print id out (from your error, is pretty clear)
{% for item in entity.items %}
{{ item.id }}
{% endfor %}
Solution 2 (Didn't tested)
You can, of course, access also data from underlying object of a form, without pass it from the controller. So you can change your snippet of code from
from
{% for content in edit_form.items %}
{{ content.getId() }}
{{ content.id() }}
{% endfor %}
to
{% for content in edit_form.vars.data %}
{{ content.id() }}
{% endfor %}
Your error was that you were trying to access FormView (passed from controller) and not entity "binded" to the form
Related
Using Symfony 4 to build a support ticket form:
Created route and functions in page controller
/**
* #Route("/support/ticket")
*/
public function ticket(){
return $this->render('support/ticket/ticket.html.twig');
}
public function new(Request $request)
{
// creates a Ticket and gives it some dummy data for this example
$ticket = new Ticket();
$form = $this->createFormBuilder($ticket)
->add('category', ChoiceType::class, array(
'choices' => array(
'ROMAC eHR' => 1,
'ROMAC Website' => 2,
'ROMAC Guide' => 3,
)
))
->add('comment', TextareaType::class)
->add('save', SubmitType::class, array('label' => 'Submit Ticket'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values
// but, the original `$task` variable has also been updated
$ticket = $form->getData();
// ... perform some action, such as saving the task to the database
// for example, if Ticket is a Doctrine entity, save it!
// $entityManager = $this->getDoctrine()->getManager();
// $entityManager->persist($task);
// $entityManager->flush();
return $this->redirectToRoute('ticket_success');
}
return $this->render('support/ticket/ticket.html.twig', array(
'form' => $form->createView(),
));
}
And then render the form in the twig template:
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.category) }}
{{ form_row(form.comment) }}
{{ form_end(form) }}
When I load the page I get a Symfony error stating that "Variable form does not exist".
I have followed the documentation https://symfony.com/doc/current/forms.html. Where/how can I find the issue?
I assume you get this error while accessing "/support/ticket"
You have "form" variable missing in this function
public function ticket(){
return $this->render('support/ticket/ticket.html.twig');
}
I will suggest to wrap your code in twig template in a "if" block
{% if form is defined %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.category) }}
{{ form_row(form.comment) }}
{{ form_end(form) }}
{% endif %}
Or you need to adjust your controller functions accordingly
In my case i have 30 entities that there are no relation between them and every entities have two columns. I wanted to have 6 or 7 entities in the one form, but i don't know what is the best way to do it? this is my code ...
this is my Controller:
public function general1Action(Request $request)
{
$example1 = new Example1();
$example2 = new Example2();
$example3 = new Example3();
$example4 = new Example4();
$formexample1 = $this->createForm('...Bundle\Form\Example1Type', $example1);
$formexample2 = $this->createForm('...Bundle\Form\ Example2Type', $example2);
$formexample3 = $this->createForm('...Bundle\Form\ Example3Type', $example3);
$fprmexample4 = $this->createForm('...Bundle\Form\Example4Type', $example4);
$example1->handleRequest($request);
$example2->handleRequest($request);
$example3->handleRequest($request);
$example4->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($example1->isSubmitted() && $example1->isValid()) {
/**
* To generate the value example1 first column(e1fc) and second column(e1sc)
*/
$prefix=$this->container->getParameter('prefix');
$e1fcCle=$em->getRepository("...Bundle:Example1")->genereCle('Example1',$prefix);
$example1->sete1fc($e1fcCle);
/**
* To generate the value example1 second column(e1sc)
*/
$example1->sete1sc("e1sc".($e1fcCle));
/**
* to check, the fields are not empty
*/
if(($formexample2["e2sc"]->getData())!=""){
$example2->sete1fc($e1fcCle);
$em->persist($example2);
}
if(($formexample3["e3sc"]->getData())!=""){
$example3->sete1fc($e1fcCle);
$em->persist($example3);
}
if(($formexample4["e4sc"]->getData())!=""){
$example4-> sete1fc($e1fcCle);
$em->persist($example4);
}
$em->persist($example1);
$em->flush();
return $this->forward('...Bundle:General...: general2',
array('E1FC' => $e1fcCle));
}
return $this->render('.../general1.html.twig', array(
'example1' => $example1,
'formExample1' => $formexample1->createView(),
'formExample2' => $formexample2->createView(),
'formExample3' => $formexample3->createView(),
'formExample4' => $formexample4->createView(),
));
}`
and this is my general1.html.twig :
{% extends 'base.html.twig' %}
{% block body %}
{{ form_start(formExample1) }}
{{ form_row(formExample2.e2sc) }}
{{ form_row(formExample3.e3sc) }}
{{ form_row(formExample4.e4sc) }}
<input type="submit" value="Next" />
{{ form_widget(formExample1._token) }}
{{ form_end(formExample1, {"render_rest":false}) }}
<ul>
<li>
Back to the list
</li>
</ul>
{% endblock %}`,
I have another question : when i try to use isValid() for the other form like this
if(($formexample2["e2sc"]->getData())!=""&& $example2->isValid())
i have this error: Fatal error: Call to a member function get...() on null
I currently getting an error if I try to render a conditionally added form element in twig. The form element was added (or not) through the form event listener mechanism and should only add the form element if a specific form option is set.
Error
Argument 1 passed to Symfony\Component\Form\FormRenderer::searchAndRenderBlock() must be an instance of Symfony\Component\Form\FormView, null given
Form
<?php
namespace Vendor\ProjectBundle\Form\Type;
// [...]
abstract class AbstractContextualInfoFormType extends AbstractFormType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('user', new UserFormType($this->getTranslator(), $this->getDoctrine()), array('error_bubbling' => true, 'validation_groups' => 'ValidationGroup'));
$creditcardForm = new CreditcardFormType($this->getTranslator(), $this->getDoctrine());
$creditcardForm->setProcess($options['process']);
$creditcardForm->setProvider($options['provider']);
if (array_key_exists('cvc', $options)) {
$creditcardForm->setRequireCvc($options['cvc']);
}
if (array_key_exists('types', $options)) {
$creditcardForm->setAllowedCreditcardTypes($options['types']);
}
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
function (FormEvent $event) use ($options) {
if (!array_key_exists('disable_creditcard', $options) OR (array_key_exists('disable_creditcard', $options) AND $options['disable_creditcard'] === true)) {
$creditcardForm = new CreditcardFormType($this->getTranslator(), $this->getDoctrine());
$creditcardForm->setProcess($options['process']);
$creditcardForm->setProvider($options['provider']);
if (array_key_exists('cvc', $options)) {
$creditcardForm->setRequireCvc($options['cvc']);
}
if (array_key_exists('types', $options)) {
$creditcardForm->setAllowedCreditcardTypes($options['types']);
}
$form = $event->getForm();
$form->add('creditcard', $creditcardForm, array('error_bubbling' => true));
}
}
);
}
}
// [...]
As you can see i try to add the credit card form only if the option disable_creditcard is not set. This all works fine until the moment I try to browse the page where I implemented the form:
Template
{% if not disable_creditcard %}
<div id="detail_creditcard" class="creditcard">
<legend>{{ 'creditcard.content.title'|trans }}</legend>
<div class="alert alert-info">
<i class="icon-info-sign"></i>
Bla bla bla text
</div>
**{{ form_row(form_data.creditcard.owner) }}**
{{ form_row(form_data.creditcard.number) }}
{{ form_row(form_data.creditcard.type) }}
{{ form_row(form_data.creditcard.validity) }}
{{ form_rest(form_data.creditcard) }}
</div>
{% endif %}
I also tried it with a surrounded conditional-if, but that doesn't work at all... I think twig needs the "not defined" creditcard form element here but cannot find it.
What is the right way for doing this? I would appreciate any help from you. :-)
Thanks!
try this:
{% if form_data.creditcard is defined %}
... your conditional code here
{% endif %}
I have a trouble with using app.session.flashbag.get('notice').
In the controller I make
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('SomeBundle:SomeEntity')->find($id);
$editForm = $this->createForm(new SomeEntityType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
$flash = $this->get('translator')->trans('Some Entity was successfully updated');
$this->get('session')->getFlashBag()->add('notice', $flash);
return $this->redirect($this->generateUrl('some_entity_edit', array('id' => $id)));
}
In editAction I'm getting information from the session:
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$flashes = $this->get('session')->getFlashBag()->get('notice', array());
//...
//...
return array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'flashes' => $flashes
);
}
And i'm trying in the TWIG get information from the session :
TWIG: {% for flashMessage in app.session.flashbag.get('notice') %}{{ flashMessage }}{% endfor %}
PHP: {% for flashMessage2 in flashes %}{{ flashMessage2 }}{% endfor %}
The app.session.flashbag.get('notice') is empty, the flashes has a value.
Do you have any ideas, why I can't get data from the app.session.flashbag.get('notice')?
Its normal behavior. You access flash in controller first, so it is returned and unset then. When you access it again then key does not exists in flashbag that way is empty.
See FlashBag::get at github
There is an easy way to handle (add/display) Symfony flash messages with FlashAlertBundle, it is standalone Symfony2 bundle implemented with pure JavaScript, so you don't have to worry about using JS libraries.
You just need the following code to render flash messages on your twig template:
{{ render_flash_alerts() }}
Available through
https://github.com/rasanga/FlashAlertBundle
https://packagist.org/packages/ras/flash-alert-bundle
I'm using a form with 2 classes ("ArticleType" and "ArticleHandler") for my class Article.
I would like to send the id of the article I've just created, but I can't manage to show this id parameter in the view :
In the controller, I send my article's id :
$handler = new ArticleHandler($form, $request, $em);
if ($handler->process()){
return $this->redirect($this->generateUrl('myproject_show', array('id' => $article->getId())) );
}
and in the view, I've got an error with :
{% block body %}
<p>the id :</p>
{{ id }}
{% endblock %}
or entity.id (as in the CRUD) :
Variable "id" does not exist...
Variable "entity.id" does not exist...
Do you know how to fix this?
Thanks
EDIT :
here's my method :
public function addAction()
{
$article = new Article();
$form = $this->createForm(new ArticleType(), $article);
$request = $this->getRequest();
$em = $this->getDoctrine()->getEntityManager();
$handler = new ArticleHandler($form, $request, $em);
if ($handler->process()){
return $this->redirect($this->generateUrl('myproject_show', array('id' => $article->getId())) );
}
return $this->render('ProjBlogBundle:Blog:add.html.twig', array(
'form' => $form->createView(),
));
}
and here's the view :
{% extends "ProjBlogBundle::layout.html.twig" %}
{% block title %}
the title - {{ parent() }}
{% endblock %}
{% block sousbody %}
<p>here's the article i've just created :</p>
{{ id }}
{% endblock %}
EDIT N°2 :
myproject_show:
pattern: /show/{id}
defaults: { _controller: ProjBlogBundle:Blog:show, id:5 }
To use a variable in a template you need to pass it when you render your template:
//ProjBlogBundle:Blog:show
public function showAction($id)
{
return $this->render('ProjBlogBundle:Blog:show.html.twig', array(
'id' => $id
));
}
$this->redirect($this->generateUrl('myproject_show', array('id' => $article->getId())) ); returns only HTTP 302-response without rendering a template, and the browser is redirected to the generated url...