I am trying to create a simple form within Symfony. Not quite sure why this is not grabbing the form variable.
Receiving error:
Variable "form" does not exist src/Thinkfasttoys/MapWatchBundle/Resources/views/Default/createMapPolicy.html.twig at line 30
Controller - DefaultController.php
class DefaultController extends Controller
{
public function policyFormAction()
{
$form = $this->createFormBuilder()
->add('name', 'text')
->add('age', 'integer')
->add('save', 'submit')
->getForm()
;
return $this->render('ThinkfasttoysMapWatchBundle:Default:createMapPolicy.html.twig', array(
'form' => $form->createView(),
));
}
View - createMapPolicy.html.twig
{% block body %}
<div class="row-fluid">
<div class="span12">
<div class="widget-box">
<h4 align="center", padding="10px 0 10px 0">Create a New MAP Policy</h4>
{{ form(form) }}
<div class="container-1">
</div><!-- /.container -->
</div><!-- /.widgetbox -->
</div>
</div>
{% endblock %}
In twig you have to display the form like this:
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
Related
I have a Custom-Entity that is registered as Sylius-Resource. This entity can have a list of images. For my usecase i followed instructions on the Docs.
I use a subclass of ImageType in order to provide the Upload-Image-Form:
ArtistImageType:
<?php
declare(strict_types=1);
namespace AppBundle\Form\Type;
use Sylius\Bundle\CoreBundle\Form\Type\ImageType;
class ArtistImageType extends ImageType
{
/**
* {#inheritdoc}
*/
public function getBlockPrefix(): string
{
return 'artist_image';
}
}
This is how I reuse this ArtistImageType in my FormType:
final class ArtistType extends AbstractResourceType
{
/**
* {#inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [
'empty_data' => '',
])
->add('firstName', TextType::class, [
'empty_data' => '',
'required' => false,
])
->add('lastName', TextType::class, [
'empty_data' => '',
])
->add('images', CollectionType::class, [
'entry_type' => ArtistImageType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'label' => 'app.images',
])
And the form.html.twig:
<div class="ui two column stackable grid">
{{ form_errors(form) }}
<div class="column">
<div class="ui segment">
<h4 class="ui dividing header">{{ 'sylius.ui.general_info'|trans }}</h4>
<div class="two fields">
{{ form_row(form.name) }}
</div>
{{ form_row(form.images) }}
</div>
<div class="ui segment">
{{ form_row(form.firstName) }}
{{ form_row(form.lastName) }}
</div>
</div>
I'm wondering how i could display the images that was already uploaded in an existing Entity similar to the Product-Form, where existing images are displayed next to the "choose file"-button?
This is what I want to achieve:
But it still gets rendered without any Preview. Apparently some further customization is necessary.
After reading Sylius code I can answer myself:
1. ArtistType::buildForm()
We need to add the attribute entry_options to pass the Artist-Entity to the ImageType:
->add('images', CollectionType::class, [
'entry_type' => ArtistImageType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'entry_options' => ['artist' => $options['data']],
'label' => 'app.images',
2. ArtistImageType
Then we made ArtistImageType fit to handle this attribute properly:
class ArtistImageType extends ImageType
{
public function buildView(FormView $view, FormInterface $form, array $options): void
{
parent::buildView($view, $form, $options);
$view->vars['artist'] = $options['artist'];
}
public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver->setDefined('artist');
$resolver->setAllowedTypes('artist', Artist::class);
}
/**
* {#inheritdoc}
*/
public function getBlockPrefix(): string
{
return 'artist_image';
}
}
Consider the getBlockPrefix-method.
3. Form-Theme:
Create a Form-Theme for the images-section:
{% extends '#SyliusUi/Form/imagesTheme.html.twig' %}
{% block artist_image_widget %}
{% spaceless %}
<div class="ui upload box segment">
{{ form_row(form.type) }}
<label for="{{ form.file.vars.id }}" class="ui icon labeled button"><i class="cloud upload icon"></i> {{ 'sylius.ui.choose_file'|trans }}</label>
{% if form.vars.value.path|default(null) is not null %}
<img class="ui small bordered image" src="{{ form.vars.value.path|imagine_filter('sylius_small') }}" alt="{{ form.vars.value.type }}" />
{% endif %}
<div class="ui hidden element">
{{ form_widget(form.file) }}
</div>
<div class="ui element">
{{- form_errors(form.file) -}}
</div>
</div>
{% endspaceless %}
{% endblock %}
Consider the block name artist_image_widget. It is the Link between Twig and getBlockPrefix-Function of the ImageType-implementation.
4. I've put the whole image-section stuff in a separate file:
_media.html.twig:
{% form_theme form '#AppBundle/Form/imagesTheme.html.twig' %}
<div class="ui" >
<h3 class="ui dividing header">{{ 'sylius.ui.media'|trans }}</h3>
<br>
{{ form_row(form.images, {'label': false}) }}
</div>
The final form:
<div class="column">
<div class="ui segment">
<h4 class="ui dividing header">{{ 'sylius.ui.general_info'|trans }}</h4>
<div class="two fields">
{{ form_row(form.name) }}
</div>
{% include 'AppBundle:Admin:_media.html.twig' %}
</div>
<div class="ui segment">
{{ form_row(form.firstName) }}
{{ form_row(form.lastName) }}
</div>
i guess that 3.Form-Theme posted by #itinance is really what fixes it (by copying widget content instead of form_row(form.images..) i've also manages to make it work). But sadly i couldnt make it work with extending '#SyliusUi/Form/imagesTheme.html.twig', even when getBlockPrefix return matching prefix for this prefix
I work on my first symfony project and I need to create nice errors for a form with an uploading input.
Actually, I change with success my parameters to a limit post of 20Mo and a limit size for an uploaded file of 20Mo.
In my entity, I have an Assert (by symfony) on my property "portfolio".
/**
* #Assert\File(
* maxSize="5M",
* mimeTypes = {"application/pdf"},
* mimeTypesMessage = "Votre fichier doit être au format PDF"
* )
*/
public $portfolio;
Btw i made my import like asked in the symfony documentation.
I have the twig expression to display my errors directly when i try to validate a wrong form.
Here is my controller's function :
public function formjob(\Swift_Mailer $mailer, Request $request)
{
$job = new JobForm();
$form = $this->createFormBuilder($job)
->add("name", TextType::class, [
"label" => "Nom :"
])
->add("firstName", TextType::class, [
"label" => "Prénom :"
])
->add("mail", EmailType::class, [
"label" => "E-mail :"
])
->add("telephone", TelType::class, [
"label" => "Tel. ",
"required" => false,
"empty_data" => "Non Renseigné"
])
->add("url", UrlType::class, [
"label" => "Envoyez-nous l’adresse internet vers vos réalisations",
"required" => false,
])
->add("portfolio", FileType::class, [
"label" => "Envoyez votre portfolio au format PDF",
"required" => false,
"error_bubbling" => true
])
->add("envoyer", SubmitType::class)
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$attachment = $data->portfolio;
$mail = $data->mail;
if(isset($attachment) || isset($data->url)) {
$message = (new \Swift_Message())
->setSubject('Formulaire Job')
->setFrom($mail)
->setTo('nicolas.trinquet#laposte.net')
->setBody(
$this->renderView(
'mail/mailjob.html.twig', [
'data' => $data
]
),
'text/html'
);
if (isset($attachment)) {
$message->attach(\Swift_Attachment::fromPath($attachment)->setFilename('portfolio.pdf')->setContentType('application/pdf'));
}
$mailer->send($message);
return $this->redirectToRoute('sent');
}
}
return $this->render('main/formJob.html.twig', [
'form'=> $form->createView(),
]);
}
And here is my template :
{% extends 'layout.html.twig' %}{% block title %}Jobs{% endblock %}{% block stylesheets %}<link rel="stylesheet" type="text/css" href="formJobs.css"> {% endblock %}{% block body %}<div class="row">
<div class="col-lg-12">
<h1 class="antiqueO">Postuler</h1>
<h2 class="robotoR">Intitulé du poste</h2>
<h3 class="robotoM">Type de poste</h3>
<p class="robotoR">Description du poste</p>
<div class="trait_noir_separation"></div>
{{ form_start(form) }}
<div class="col-lg-12">
{{ form_label(form.name) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.name) }}
{{ form_widget(form.name) }}
</div>
<div class="col-lg-12">
{{ form_label(form.firstName) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.firstName) }}
{{ form_widget(form.firstName) }}
</div>
<div class="col-lg-12">
{{ form_label(form.mail) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.mail) }}
{{ form_widget(form.mail) }}
</div>
<div class="col-lg-12">
{{ form_label(form.telephone) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.telephone) }}
{{ form_widget(form.telephone) }}
</div>
<div class="col-lg-12">
{{ form_label(form.url) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.url) }}
{{ form_widget(form.url) }}
</div>
<div class="col-lg-12">
{{ form_label(form.portfolio) }}
</div>
<div class="col-lg-12">
{{ form_errors(form.portfolio) }}
{{ form_widget(form.portfolio, {'attr': {'class': 'form-control-file', 'accept' : 'application/pdf'}})}}
</div>
<div>
{{ form_widget(form.envoyer, {'attr': {'class': 'antiqueO send_button'}}) }}
</div>
{{ form_end(form) }}
</div>
</div>{% endblock body %}
Actually i have a problem : all my errors can be triggered and displayed.
BUT the error on my file input refuse to be displayed even if i have the error in my profiler toolbar :
Profiler Toolbar for size error
Profiler Toolbar for format error
What is the problem in my code? What is blocking my error display?
Based in https://symfony.com/doc/current/reference/forms/types/text.html#error-bubbling
error_bubbling
type: boolean default: false unless the form is compound
If true, any errors for this field will be passed to the parent field or form. For example, if set to true on a normal field, any errors for that field will be attached to the main form, not to the specific field.
So as you are using this attribute in portfilo property, the error is showing on
{{ form_errors(form) }}
and not in
{{ form_errors(form.portfolio) }}
Just try to remove error_bubbling from portfolio property in formjob function and the error should be showed in your form
I am doing a web application with symfony3 and I need a way to let the users to edit and update their profile. I used FosUserBundle to manage the the users access but i don't know what steps to take to solve my problem.
Does someone have some ideas or useful links to share ?
thank you
I Solved the problem. Yes it's my first question on stackoverflow and I'm learning.
here is my code:
dogController.php
/**
* #Route("/profile/edit", name= "edit_profile" )
*/
public function edit_profileAction(Request $request)
{
$user = $this->getUser();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isValid()) {
/** #var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->get('fos_user.user_manager');
$event = new FormEvent($form, $request);
$dispatcher = $this->get('event_dispatcher');
$dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
//$url = $this->generateUrl('fos_user_profile_show');
$url = $this->generateUrl('edit_profile');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(FOSUserEvents::PROFILE_EDIT_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
$this->get('session')->getFlashBag()->add(
'notice',
'Profile Updated!'
);
return $response;
}
return $this->render('dog/edit_profile.html.twig',array('form'=>$form->createView()));
}
UserType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Vich\UploaderBundle\Form\Type\VichImageType;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class UserType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options){
$builder->add('username')
->add('name')
->add('surname')
->add('email')
->add('telephone')
->add('imageFile', FileType::Class );
}
public function setDefaultOptions(OptionsResolverInterface $resolver){
$resolver->setDefaults( array('data_class' => 'AppBundle\Entity\User') );
}
public function getName() {
return 'appBundle_user';
}`enter code here`
}
edit_profile.html.twig
<header>
<div class="container">
<div class="row">
<div class="col-lg-12">
<h2 class="name">Edit Profile</h2>
<div class="row" >
<div class="col-lg-12">
<div class="input_width" >
{% for flashMessage in app.session.flashbag.get('notice') %}
<div class="alert alert-success alert">
{{ flashMessage }}
</div>
{% endfor %}
{{form_start(form, {'attr': {'class': 'form-horizontal'}} )}}
{{ form_errors(form) }}
<div class="form-group">
{{ form_label(form.username) }}
{{ form_errors(form.username) }}
{{ form_widget(form.username , {'attr': {'class': 'form-control'}} ) }}
</div>
<div class="form-group">
{{ form_label(form.email) }}
{{ form_errors(form.email) }}
{{ form_widget(form.email , {'attr': {'class': 'form-control'}} ) }}
</div>
<div class="form-group">
{{ form_label(form.name) }}
{{ form_errors(form.name) }}
{{ form_widget(form.name , {'attr': {'class': 'form-control'}} ) }}
</div>
<div class="form-group">
{{ form_label(form.surname) }}
{{ form_errors(form.surname) }}
{{ form_widget(form.surname, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form.telephone) }}
{{ form_errors(form.telephone) }}
{{ form_widget(form.telephone, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form.imageFile) }}
{{ form_errors(form.imageFile) }}
{{ form_widget(form.imageFile) }}
</div>
<input type="submit" value="Submit" class="btn btn-default bluInput " />
{{form_end(form)}}
</div>
</div>
</div>
</div>
</div>
</div>
</header>
Basically I had to create a form type class linked to my entity, then, use it in my controller as long as the Fos user bundle user manager.
I'm trying to create simple form but for some reason input fields are not rendered. The source code shows that the open and close tag of form are rendered but not the input fields itself.
Here is the code
namespace SDProjectBundle\Forms;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class UserForm extends AbstractType
{
public function formBuilder(FormBuilderInterface $builder, array $options)
{
$builder->add('email', 'text')
->add('password', 'password')
->add('Send', 'submit');
}
public function getName()
{
return 'app_users';
}
}
namespace SDProjectBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use SDProjectBundle\Forms\UserForm;
use SDProjectBundle\Entity\User;
class UsersController extends Controller
{
public function addAction(Request $request)
{
$form = $this->createForm(new UserForm(), new User());
return $this->render('SDProjectBundle:Users:add.html.twig', array(
'form' => $form->createView(),
));
}
}
add.html.twig
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
What I'm doing wrong?
You implements the wrong method in the form class: you need to implements the buildForm method of your custom form type.
Practically, in the UserForm class, you need to put this:
public function buildForm(FormBuilderInterface $builder, array $options)
instead of
public function formBuilder(FormBuilderInterface $builder, array $options)
Hope this help
If you want to render the form component try with
{{ form_widget(form) }}
instead of
{{ form_label(form) }}
If you want to render only the label of the field you need to specify the field as:
{{ form_label(form.email) }}
A complete manually rendered version of your form can be:
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_label(form.email) }}
{{ form_errors(form.email) }}
{{ form_widget(form.email) }}
</div>
<div>
{{ form_label(form. password) }}
{{ form_errors(form. password) }}
{{ form_widget(form. password) }}
</div>
<div>
{{ form_widget(form. Send) }}
</div>
{{ form_end(form) }}
Try this in your TWIG:
{% block form_row %}
{% spaceless %}
<div class="form-group">
{{ form_label(form) }}
<div>
{{ form_widget(form) }}
</div>
</div>
{% endspaceless %}
{% endblock form_row %}
why does my symfony2 Form not submit?
If i press the submit-button, nothing happens.
I want not the default-form {{ form(form) }}.
The default form works.
The error seems to be in TWIG?
{% extends '::base.html.twig' %}
{% block stylesheets %}
{{ parent() }}
<link href="{{ asset('css/essensplan/show.css') }}" rel="stylesheet" />
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
{% endblock %}
{% block body -%}
{{ form_start(form) }}
<h1>Speiseplan für KW {{ kw }}</h1>
<form action = "" method = "post">
<input type="submit" name="back" value="<" class="btn-lg btn-success"/>
<input type="submit" name="next" value=">" class="btn-lg btn-success" />
<input type="hidden" name="kw" value="{{ kw }}">
</form>
<div class="container-fluid">
<div class="tag col-xs-3">
<div class="wochentag">
Montag
</div>
<div class="hauptgericht">
<div class="h"><strong>Hauptgericht</strong></div>
<div class=""> {{ form_widget(form.montagHauptgericht) }}
</div>
</div>
<div class="nachtisch">
<div class="n"><strong>Nachtisch</strong></div>
<div class=""> {{ form_widget(form.montagNachtisch) }} </div>
</div>
</div>
</div>
{{ form_widget(form.Eintragen) }}
{{ form_end(form) }}
{% endblock %}
<?php
namespace Chris\TestBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Chris\TestBundle\Entity\KW;
use Chris\TestBundle\Form\KWType;
use Symfony\Component\HttpFoundation\Session\Session;
/**
* Admin controller.
*
*/
class AdminController extends Controller
{
/**
* Lists all KW entities.
*
*/
public function adminAction(Request $request)
{
$jahr = "2014";
$kw = "43";
// $_GET parameters
// Änderung
if ($request->get('next')){
$kw = (intval($request->get('kw'))+1) . "";
//var_dump($kw);
}
if ($request->get('back')){
$kw = (intval($request->get('kw'))-1) . "";
//var_dump($kw);
}
$form = $this->createFormBuilder()
->add('montagHauptgericht', 'text')
->add('montagNachtisch', 'text')
->add('Eintragen', 'submit')
->getForm();
$form->handleRequest($request);
// data is an array with "name", "email", and "message" keys
$data = $form->getData();
return $this->render('ChrisTestBundle:KW:admin.html.twig', array(
'form' => $form->createView(), 'kw' => $kw
));
}
}
Thanks for your help.
It seems that you have nested forms in your markup (first one coming from twig's {{ form }} second is in markup. According to this or this you are not allowed to nest form tags. This might be the reason your form is not submitting properly