Symfony : CreateForm / Why my textarea do not appear? - css

I have a problem to display a textarea from a form I've created with Symfony.
The textarea appears in html but it has no display: block in the css. It has nothing in the css, to be clear.
When I add a display:block in the css myself, it simply stripped by chrome/firefox.
The problem only happens when I create the form from a separate Class, not when I create it in controller's function.
Here is my code:
AdController.php
<?php
namespace App\Controller;
use App\Entity\Ad;
use App\Form\AdType;
use App\Repository\AdRepository;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AdController extends AbstractController
{
/**
* Create ad
*
* #Route("/ads/new", name="ads_create")
*
* #return Response
*/
public function create(){
$ad = new Ad();
$form = $this->createForm(AdType::class, $ad);
return $this->render('ad/new.html.twig', [
'form' => $form->createView()
]);
}
}
AdType.php
<?php
namespace App\Form;
use App\Entity\Ad;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
class AdType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title')
->add('slug')
->add('price')
->add('introduction')
->add('content', TextareaType::class, [
'attr' => array('cols' => '5', 'rows' => '5')])
->add('coverImage')
->add('rooms')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Ad::class,
]);
}
}
And twig :
{% extends 'base.html.twig' %}
{% form_theme form 'bootstrap_4_layout.html.twig' %}
{% block title %}Create ad{% endblock %}
{% block body %}
<div class="container">
<h1>lorem ipsum</h1>
{{form_start(form)}}
{{ form(form) }}
{{form_end(form)}}
</div>
{% endblock %}
I tried a lot of things but I still don't understand how to solve this problem. Do someone have an idea about it ?
Thanks in advance !

I had the same problem
SOLUTION was to disable AdBlock
Adblock hid the textarea beacause it thought it was an ad (your entities name begin with the "ad" prefix)

My first guess would be that content is some kind of reserved word.
What happens when you rename the property?
Additionally, try rendering the form widgets separately, such as :
{{ form_widget(form.title) }}
{{ form_widget(form.slug) }}
...
{{ form_widget(form.content) }}
...
If that gives you any error - you will have some more information you can debug

cache problem of your browser empty chrome cache or use private browser

Related

Pass custom data to Form Theme in Symfony/Twig

I'm new to Symfony, currently working with 4.4, and am trying to implement a simple form theme for one specific form, i.e. the theme is in the same file as the form's html.twig file. I have my own form_row block and I'm trying to pass in custom data (an icon to use within the div) when calling it, so something like (this is highly summarised!):
{{ form_row(signUpForm.email, {
attr: { placeholder: 'e.g. bobsmith#gmail.com' },
icon: 'envelope'
}) }}
then try to render in the form as
{%- block form_row -%}
<div>
{{ form_label(form) }}
{{ form_widget(form, {attr: class: 'input'}) }}
<i class="icon {{ icon }}"></i>
</div>
I tried also passing icon via the formBuilder, along the lines of
$builder
->add('email', EmailType::class, [
'attr'=> ['icon' => 'envelope']
])
but no joy. Surely this must be possible! Any assistance would be much appreciated. Thanks
I'm not sure but you can access to your form variable with {{form}} in your theme. So you can use it.
Hope this help
Edit:
You can add property in your entity and use it in template like this :
{%- block form_row -%}
<div>
{{ form_label(form) }}
{{ form_widget(form, {attr: class: 'input'}) }}
{% set myData = form.vars.value %}
<i class="icon {% if myData.type == 'mail' %}envelope{% endif %}"></i>
I think you have a better way to do this but i do something like that and it's work.
So, I managed to find the "proper" way to do what I want: a Form Type Extension. The Symfony Casts tutorial on it is pretty good. In short, you create a class to extend your main form input class; in my case I was dealing with a text based input, so I created an App\Form\ypeExtension\TextIconExtension class, extended from FormTypeExtensionInterface, then implemented configureOptions and buildView (I removed the functions in the interface I didn't fill in):
class TextIconExtension implements FormTypeExtensionInterface
{
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['icon'] = $options['icon'];
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'icon' => 'user'
]);
}
public function getExtendedType()
{
return TextType::class;
}
public function getExtendedTypes(): iterable
{
return [TextType::class];
}
}
Then, in my form template, I can simply pass a value for icon:
{{ form_row(signUpForm.email, {
attr: { placeholder: 'e.g. bobsmith#gmail.com' },
icon: 'envelope'
}) }}

reusable dynamic sidebar in Symfony 4 (Twig)?

I recently started using Symfony 4 and I am creating my first website with this wonderful framework right now.
I have a sidebar that should be displayed in about half of my routes and the content of the sidebar should be filled with some data from a database.
Currently I use DI in all this routes and pass the result of the injected repository to the template (which includes my sidebar.html.twig) for the route.
public function chalupaBatman(FancyRepository $repository)
{
$sidebarObjects = $repository->getSidebarObjects();
$this->render('controllername/chalupabatman.html.twig', [
'sidebarObjects' => $sidebarObjects,
]);
}
I am wondering if there is a way to avoid this for every route I define in my controllers.
So far I found this topic on stackoverflow.
The User Mvin described my problem in a perfect way and also provided some solutions.
However there is still no answer to "what is the best practice" part also the topic is from 2017; therefor, the way to solve this may have changed in Symfony 4.
I ended up with a TwigExtension solution. I'll describe how to achieve it and it would be great if you guys could provide some feedback.
Let me know if I produce massive overhead or miss something essential ;-)
Alright, first of all I created a TwigExtension via command-line
php bin/console make:twig-extension AppExtension
And then I modified the class to look like this:
<?php
namespace App\Twig;
use App\Repository\ArticleRepository;
use Psr\Container\ContainerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
class AppExtension extends AbstractExtension implements ServiceSubscriberInterface
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function getFunctions(): array
{
return [
new TwigFunction('article_sidebar', [$this, 'getArticleSidebar'], ['needs_environment' => true, 'is_safe' => ['html']]),
];
}
public function getArticleSidebar(\Twig_Environment $twig)
{
$articleRepository = $this->container->get(ArticleRepository::class);
$archive = $articleRepository->myAwesomeLogic('omegalul');
return $twig->render('/article/sidebar.html.twig', [
'archive' => $archive,
]);
}
public static function getSubscribedServices()
{
return [
ArticleRepository::class,
];
}
}
In order to activate Lazy Performance so our Repository and the additional Twig_Environment doesn't get instantiated everytime when we use Twig
we implement the ServiceSubscriberInterface and add the getSubscribedServices-method.
Therefor, our Repo and Twig_Environment only gets instantiated when we actually call {{ article_sidebar() }} inside a template.
{# example-template article_base.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<div class="row">
<div class="col-10">
{% block article_body %}{% endblock %}
</div>
<div class="col-2">
{{ article_sidebar() }}
</div>
</div>
{% endblock %}
Now I am able to define my templates for the article-routes like this:
{# example-template /article/show.html.twig #}
{% extends 'article_base.html.twig' %}
{% block article_body %}
{# display the article here #}
{% endblock %}

Symfony - checkbox select ALL

I have a multiple select checkbox in SYMFONY, in a form builder, but i want to have a 'select all' that select all the selection of my entity.
I try a lots of solution with jquery, but nothing works.
here's my code Controller
<?php
namespace AdminBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Validator\Constraints as Assert;
use AdminBundle\Entity\Equipments;
use AdminBundle\Repository\Metier;
class EquipementsController extends Controller
{
/**
* #Route("/", name="homepage")
*/
public function indexAction(Request $request)
{
//$metiers = $this->getDoctrine()->getManager()->getRepository('AdminBundle:Metier')->getForSearch();
$form = $this->createFormBuilder()
->add('metier', EntityType::class, array('class' => 'AdminBundle:Metier', 'choice_label' => 'name','required' => false, 'expanded' => true, 'placeholder' => 'Tous', 'multiple' => true,
and my twig
{{ form_start(form) }}
{{ form_errors(form) }}
<fieldset><legend><b>Filière</b></legend>
{{ form_row(form.metier) }}
</fieldset>
<fieldset><legend><b>Opération</b></legend>
{{ form_row(form.operation) }}
</fieldset>
{{ form(form) }}
{{ form_end(form) }}
Adjust your twig template to include a checkbox for select all:
{{ form.row(form.checkboxes, {'attr': {'class': 'class-name-of-checkboxes'} }) }}
<input type="checkbox" id="select-all" name="select-all" /> Select All
Changing .checkboxes to your relevant form field for your checkboxes. What the above does is add a class to the input called class-name-of-checkboxes (change to something more suitable like form-checkbox).
This then adds a checkbox underneath that has no relation to any of the form data, all it does is add a checkbox with an id of select-all to allow the user to select all checkboxes at once.
then jQuery:
$('#select-all').on('change', function()
{
if ($(this).is(':checked')) {
$('.class-name-of-checkboxes').attr('checked', 'checked')
}
})
The jQuery then uses .on('change') on the $('#select-all') checkbox object to run a function, if the checkbox is checked, add an attribute of checked="checked" to all inputs with class .class-name-of-checkboxes
refs:
https://api.jquery.com/attr/
https://api.jquery.com/is/

Overriding SensioGeneratorBundle's twig template: trying to translate the delete button

I'm trying to override Resources/crud/actions/delete.php.twig from SensioGeneratorBundle.
I created this file located at app/Resources/SensioGeneratorBundle/skeleton/crud/actions/delete.php.twig:
{% extends "#SensioGenerator/Resources/crud/actions/delete.php.twig" %}
{% block form %}
/**
* Creates a form to delete a {{ entity }} entity by id.
*
* #param mixed $id The entity id
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('{{ route_name_prefix }}_delete', array('id' => $id)))
->setMethod('DELETE')
->add('submit', 'submit', array('label' => 'Supprimer'))
->getForm()
;
}
{% endblock form %}
Problem is that #SensioGenerator is not recognized:
There are no registered paths for namespace "SensioGenerator" in "crud/controller.php.twig" at line 58.
I tried to manually register the namespace in app/config/config.yml:
twig:
[...]
paths:
"%kernel.root_dir%/../vendor/sensio/generator-bundle/Sensio/Bundle/GeneratorBundle/": SensioGenerator
But still not working. Idea?
Why you didn't do it like in docs ? SensioGeneratorDocs
{% extends "skeleton/crud/actions/delete.php.twig" %}
{% block form %}
/**
* Creates a form to delete a {{ entity }} entity by id.
*
* #param mixed $id The entity id
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm($id)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('{{ route_name_prefix }}_delete', array('id' => $id)))
->add('submit', 'submit', array('label' => 'Supprimer'))
->getForm()
;
}
{% endblock form %}
If you're using a project that's based-on or is similar-to the Symfony Standard Edition, then the SensioGeneratorBundle is only loaded for the dev environment.
This is configured in both the composer.json and the AppKernel.
So, make sure your execution is using the dev environment or alter these configurations so that the bundle is always loaded.

How to clear a date in a form (Symfony2)?

I would like to make a date clearable in a form (for example, with a little cross). The date field is already filled and I want to clear data. Is there an easy way to do this ?
My date is nullable and the option is set to 'required'=>false.
Here is the form class :
// Namespaces...
class FormRre extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
// Other $builder->add() properties...
$builder->add('rredatefin', 'date', array('required' => false));
}
public function getName()
{
return 'sn';
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'Creasixtine\AFBundle\Entity\Rre',
);
}
}
And here is the way it is currently displayed :
{% extends 'CreasixtineAFBundle:Default:index.html.twig' %}
{% block main_container %}
{# ... #}
<form action="{{ path('planifier') }}" method="post" {{ form_enctype(form) }}>
{{ form_errors(form) }}
<div class="bloc-input">{{ form_label(form.rredatefin, "Date de réexpédition :") }}
{{ form_widget(form.rredatefin) }}
</div>
<input type="submit" />
</form>
{% endblock %}
Thanks by advance.
EDIT : precisions in answer to How to clear a date in a form (Symfony2)?
I'm not quite sure to understand.
If you made your date nullable and not required, just leave the field empty.
It should be enough.
Am I missing something ?
After comment edit
I'd advice you, as usual, to work with jquery.
And the .val() function in particular.
=> http://api.jquery.com/val/
$('#Devis_tarif_bi_horaire_select').change(function()
{
$('#Devis_tarif_bi_horaire_value').val('')
});
For instance, this little script will clear the input with id=Devis_tarif_bi_horaire_value when a select with id=Devis_tarif_bi_horaire_select is modified.
You may trigger the .val() function with a click on a link (http://api.jquery.com/click/), or anything you want.
Have a nice try.

Resources