How to display the current picture above the upload field in SonataAdminBundle? - php

I am using SonataAdminBundle (with Doctrine2 ORM) and I have successfully added a file upload feature to my Picture model.
I would like, on the Show and Edit pages, to display a simple <img src="{{ picture.url }} alt="{{ picture.title }} /> tag just above the relevant form field (provided that the Picture being edited is not new, of course), so that the user may see the current photo, and decide whether to change it or not.
After hours of research, I've been unable to figure out how to do it. I suppose I need to override some template, but I'm a bit lost...
Can somebody give me a hint?
Thank you!
Here is the relevant section of my PictureAdmin class.
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('category', NULL, ['label' => 'Catégorie'])
->add('title', NULL, ['label' => 'Titre'])
->add('file', 'file', ['required' => false, 'label' => 'Fichier']) // Add picture near this field
->add('creation_date', NULL, ['label' => 'Date d\'ajout'])
->add('visible', NULL, ['required' => false, 'label' => 'Visible'])
->add('position', NULL, ['label' => 'Position']);
}
protected function configureShowFields(ShowMapper $showMapper)
{
$showMapper
->add('id', NULL, ['label' => 'ID'])
->add('category', NULL, ['label' => 'Catégorie'])
->add('title', NULL, ['label' => 'Titre'])
->add('slug', NULL, ['label' => 'Titre (URL)'])
->add('creation_date', NULL, ['label' => 'Date d\'ajout'])
->add('visible', NULL, ['label' => 'Visible'])
->add('position', NULL, ['label' => 'Position']);
// Add picture somewhere
}

I have managed to put the image above the field in the edit form. But my solution is a little bit specific, because I use Vich Uploader Bundle to handle uploads, so the generation of the image url was a little bit easier thanks to bundle helpers.
Let's look at my example, a film poster field in a film entity.
This is part of my admin class:
//MyCompany/MyBundle/Admin/FilmAdmin.php
class FilmAdmin extends Admin {
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('title')
....
->add('poster', 'mybundle_admin_image', array(
'required' => false,
))
}
mybundle_admin_image is handled by a custom field type, that is just a child of file type by setting it's getParent method: (don't forget to register your type class as a service)
//MyCompany/MyBundle/Form/Type/MyBundleAdminImageType.php
public function getParent()
{
return 'file';
}
Then I have a template that extends Sonata's default styling, and I have it included in the admin class:
//MyCompany/MyBundle/Admin/FilmAdmin.php
public function getFormTheme() {
return array('MyCompanyMyBundle:Form:mycompany_admin_fields.html.twig');
}
And finally I have a block for my custom image type that extends the basic file type:
//MyCompany/MyBundle/Resources/views/Form/mycompany_admin_fields.html.twig
{% block mybundle_admin_image_widget %}
{% spaceless %}
{% set subject = form.parent.vars.value %}
{% if subject.id and attribute(subject, name) %}
<a href="{{ asset(vich_uploader_asset(subject, name)) }}" target="_blank">
<img src="{{ asset(vich_uploader_asset(subject, name)) }}" width="200" />
</a><br/>
{% endif %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% endspaceless %}
{% endblock %}
This causes that a 200px wide preview of image (if exists) is shown above the upload field, linked to it's full size version opening in new tab. You can customize it as you want, e.g. adding a lightbox plugin.

you can easily do this on edit page by helpers(FormMapper->setHelps) or option "help" pass on FormMapper
protected function configureFormFields(FormMapper $formMapper) {
$options = array('required' => false);
if (($subject = $this->getSubject()) && $subject->getPhoto()) {
$path = $subject->getPhotoWebPath();
$options['help'] = '<img src="' . $path . '" />';
}
$formMapper
->add('title')
->add('description')
->add('createdAt', null, array('data' => new \DateTime()))
->add('photoFile', 'file', $options)
;
}

You can easily do this on show page
by template attribute pass on $showmapper
->add('picture', NULL, array(
'template' => 'MyProjectBundle:Project:mytemplate.html.twig'
);
and inside your template you get current object so u can call get method and pull image path
<th>{% block name %}{{ admin.trans(field_description.label) }}{% endblock %}</th>
<td>
<img src="{{ object.getFile }}" title="{{ object.getTitle }}" />
</br>
{% block field %}{{ value|nl2br }}{% endblock %}
</td>
To show image in edit mode you have to override fileType or you have to create your own customType on top of fileType
There is also some bundle which is having this kind of functionality
check out this GenemuFormBundle

Solution for Symfony3
The answer from #kkochanski is the cleanest way I found so far. Here a version ported to Symfony3. I also fixed some bugs.
Create a new template image.html.twig for your new form type (full path: src/AppBundle/Resources/views/Form/image.html.twig):
{% block image_widget %}
{% spaceless %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
{% if image_web_path is not empty %}
<img src="{{ image_web_path }}" alt="image_photo"/>
{% endif %}
{% endspaceless %}
{% endblock %}
Register the new form type template in your config.yml:
twig:
form_themes:
- AppBundle::Form/image.html.twig
Create a new form type and save it as ImageType.php (full path: src/AppBundle/Form/Type/ImageType.php):
<?php
namespace AppBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilderInterface;
/**
* Class ImageType
*
* #package AppBundle\Form\Type
*/
class ImageType extends AbstractType
{
/**
* #return string
*/
public function getParent()
{
return 'file';
}
/**
* #return string
*/
public function getName()
{
return 'image';
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'image_web_path' => ''
));
}
/**
* #param FormView $view
* #param FormInterface $form
* #param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['image_web_path'] = $options['image_web_path'];
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAttribute('image_web_path', $options['image_web_path'])
;
}
}
If you have done this. You can just import the new ImageType in your entity admin class:
use AppBundle\Form\Type\ImageType
And then, finally use the new form type without any inline-html or boilerplate code in configureFormFields:
$formMapper
->add('imageFile', ImageType::class, ['image_web_path' => $image->getImagePath()])
;
Instead of $image->getImagePath() you have to call your own method that returns the url to your image.
Screenshots
Creating a new image entity using sonata admin:
Editing a image entity using sonata admin:

You can simple do by this way
$image = $this->getSubject();
$imageSmall = '';
if($image){
$container = $this->getConfigurationPool()->getContainer();
$media = $container->get('sonata.media.twig.extension');
$format = 'small';
if($webPath = $image->getImageSmall()){
$imageSmall = '<img src="'.$media->path($image->getImageSmall(), $format).'" class="admin-preview" />';
}
}
$formMapper->add('imageSmall', 'sonata_media_type', array(
'provider' => 'sonata.media.provider.image',
'context' => 'default',
'help' => $imageSmall
));

Teo.sk wrote the method of showing images using VichUploader. I found an option which allow you to show images without this bundle.
First we need to create our form_type. There is tutorial: symfony_tutorial
In main Admin class:
namespace Your\Bundle;
//.....//
class ApplicationsAdmin extends Admin {
//...//
public function getFormTheme() {
return array_merge(
parent::getFormTheme(),
array('YourBundle:Form:image_type.html.twig') //your path to form_type template
);
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper->add('file_photo', 'image', array(
'data_class' => 'Symfony\Component\HttpFoundation\File\File',
'label' => 'Photo',
'image_web_path' => $this->getRequest()->getBasePath().'/'.$subject->getWebPathPhoto()// it's a my name of common getWebPath method
))
//....//
;
}
}
Next part is a code from ImageType class.
namespace Your\Bundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormBuilderInterface;
class ImageType extends AbstractType
{
public function getParent()
{
return 'file';
}
public function getName()
{
return 'image';
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'image_web_path' => ''
));
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['image_web_path'] = $options['image_web_path'];
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->setAttribute('image_web_path', $options['image_web_path'])
;
}
}
And on the end time for image_type twig template.
{% block image_widget %}
{% spaceless %}
{% set type = type|default('file') %}
<input type="{{ type }}" {{ block('widget_attributes') }} {% if value is not empty %}value="{{ value }}" {% endif %}/>
<img src="{{ image_web_path }}" alt="image_photo"/>
{% endspaceless %}
{% endblock %}
For me it's working! I'm also using avalanche bundle to resize images.

There is an easy way - but you will see the picture below the upload button.
SonataAdmin lets put raw HTML into the ‘help’ option for any given form field. You can use this functionality to embed an image tag:
protected function configureFormFields(FormMapper $formMapper) {
$object = $this->getSubject();
$container = $this->getConfigurationPool()->getContainer();
$fullPath = $container->get('request')->getBasePath().'/'.$object->getWebPath();
$formMapper->add('file', 'file', array('help' => is_file($object->getAbsolutePath() . $object->getPlanPath()) ? '<img src="' . $fullPath . $object->getPlanPath() . '" class="admin-preview" />' : 'Picture is not avialable')
}

Related

How display image in edit form Symfony 5

I have form where i upload files - it work so good, i put image name into database, showing it on main page. But if i want to go to edit information about this image e.g name or description form row with image i have empty and once again i need to upload the same photo:
edit form
Project Entity:
/**
* #ORM\Column(type="string", length=255)
*/
private $page_path;
public function getPhotoPath(): ?string
{
return $this->photo_path;
}
public function setPhotoPath(string $photo_path): self
{
$this->photo_path = $photo_path;
return $this;
}
ProjectFormType:
<?php
namespace App\Form;
use App\Entity\Projects;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class ProjectsType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class, [])
->add('page_path', TextType::class, [])
->add('description', TextType::class, [])
->add('photo_path', FileType::class, [
'data_class' => null,
'label' => 'Zdjęcie',
'constraints' => [
'maxSize' => '5M',
'mimeTypes' => [
'image/*'
],
'mimeTypesMessage' => 'Obsługiwany format pliku musi być obrazem'
]
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Projects::class,
]);
}
}
View:
{% extends 'baseAdmin.html.twig' %}
{% block title %}{{ parent() }}New/Edit
{% endblock %}
{% block body %}
<div class="card-body">
{% form_theme projectsForm 'bootstrap_4_layout.html.twig' %}
{{ form_start(projectsForm) }}
{{ form_row(projectsForm.name) }}
{{ form_row(projectsForm.page_path) }}
{{ form_row(projectsForm.description) }}
{{ form_row(projectsForm.photo_path) }}
<button type="submit" class="btn btn-primary mb-5">Submit</button>
{{ form_end(projectsForm) }}
</div>
{% endblock %}
File input should be empty when edit your entity and this is the default behavior. to make it required false in edit you can use add this simple solution.
'required'=> is_null($builder->getData()->getId())
if you upload a new image, it should replace the old one, otherwise do nothing.
if you want to show the image, you can do it directly in the twig with <img> tag

Symfony forms problem- Variable form does not exist

I am building a crud app using symfony 4. Here is the controller code:
<?php
namespace App\Controller;
use App\Entity\Taskslist;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
class TodoController extends Controller{
/**
* #Route("/",name="todo_list")
*/
public function listAction(){
$todos=$this->getDoctrine()->getRepository('App:Taskslist')->findAll();
return $this->render('todo/index.html.twig',array('todos' => $todos));
}
/**
* #Route("/todo/create",name="todo_create")
*/
public function createAction(Request $request){
$todo = new Taskslist;
$form = $this->createFormBuilder($todo)
->add('id', TextType::class)
->add('title', TextType::class)
->add('description', TextareaType::class)
// ->add('priority', ChoiceType::class, array('choices' => array('Low' => 'Low', 'Normal' => 'Normal', 'High'=>'High'), 'attr' => array('class' => 'form-control', 'style' => 'margin-bottom:15px')))
// ->add('status', BooleanType::class, array('attr' => array('class' => 'form-control', 'style' => 'margin-bottom:15px')))
->add('Save', SubmitType::class, array('label'=> 'Create Todo'))
->getForm();
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$name = $form['id']->getData();
$category = $form['title']->getData();
$description = $form['description']->getData();
//$due_date = $form['status']->getData();
//$name = $form['name']->getData();
//$now = new\DateTime('now');
$todo->setId($name);
$todo->setTitle($category);
$todo->setDescription($description);
$sn = $this->getDoctrine()->getManager();
$sn -> persist($todo);
$sn -> flush();
return $this->redirectToRoute('todo_list');
}
return $this->render('todos/create.html.twig', array(
'form' => $form->createView()
));
}
/**
* #Route("/todo/edit/{id}",name="todo_edit")
*/
public function editAction($id,Request $request){
return $this->render('todo/edit.html.twig');
}
/**
* #Route("/todo/details/{id}",name="todo_details")
*/
public function detailsAction($id){
return $this->render('todo/details.html.twig');
}
}
And here is the edit.html.twig:
{% extends 'base.html.twig' %}
{% if form is defined %}
{% block body %}
{{form_start(form)}}
{{form_widget(form)}}
{{form_end(form)}}
{% endblock %}
{% endif %}
I followed all the tutorials but got this error when i click the edit button :
variable form does not exist.
Although my code steps into the if statement.
Can you please help me?Thanks in advance.i couldn't find any working solution
I think the issue is here:
{% extends 'base.html.twig' %}
{% if form is defined %}
{% block body %}
{{form_start(form)}}
{{form_widget(form)}}
{{form_end(form)}}
{% endblock %}
{% endif %}
use this instead:
{% extends 'base.html.twig' %}
{% block body %}
{{form_start(form)}}
{{form_widget(form)}}
{{form_end(form)}}
{% endblock %}

Symfony form inline radios with text fields

In Symfony I have a twig page that displays a form with text fields and check boxes. The form contains data for a question and four possible answers. The user can edit the data and select one answer that is correct.
At the moment I have all the text fields where the user can change the data and four check boxes. Instead of the check boxes I need radio buttons(this is to allow the user to select only one choice). Also I need the check boxes to be on the right hand side of text fields for each possible answer. How can I do this in Symfony. Would much appreciate some help.Thanks.
Using Collection of Forms to build the entire Form
Answer Form:
class AnswerFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('answer');
$builder ->add('isCorrect', null , array('label' => false,));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array('data_class' => 'QuizBundle\Entity\Answer'));
}
public function getName()
{
return 'quiz_bundle_answer_form_type';
}
}
Question Form:
class QuestionFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('image');
$builder->add('question');
$builder->add('answers', CollectionType::class, array('entry_type' => AnswerFormType::class));
$builder->add('Submit', SubmitType::class, array('label' => 'Submit'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array('data_class' => 'QuizBundle\Entity\Question'));
}
public function getName()
{
return 'quiz_bundle_question_form_type';
}
}
This is my Twig:
{% extends 'base.html.twig' %}
{% block body %}
Edit record page
{{ form_start(form) }}
{{ form_row(form.image) }}
{{ form_row(form.question) }}
{% for answers in form.answers %}
<li>{{ form_row(answers.answer) }}</li>
{% endfor %}
{{ form_end(form) }}
{% endblock %}
You can not mix a radio input with text inputs to let the user edit them.
It is not possible with HTML.
No other choice, you have to :
Recreate the radio behavior with Javascript on the client side
Write some CSS to make your checkboxes looks like radio boxes.
Attach a form constraint which validates only one checkbox is selected after submit.
To put the text inputs at the right side, you have to customize the form widgets. Take a look at the documentation : http://symfony.com/doc/current/cookbook/form/form_customization.html
I understand what you are trying to do because of your previous question. For layout of the form, you can do something like this to make it look better:
{{ form_start(form) }}
{{ form_label(form.image) }}{{ form_widget(form.image) }}
{{ form_label(form.question) }}{{ form_widget(form.question) }}
{% for ans in form.answers %}
<li>{{ form_label(ans.answer) }}{{ form_widget(ans.answer) }}
{{ form_label(ans.isCorrect) }}{{ form_widget(ans.isCorrect) </li>
{{ form_end(form) }}
However, I don't think this is the solution for you. Like Alsatian mentioned, you need to use Javascript to check for "onchange" events for the radio buttons. You are creating a form class, which in my opinion doesn't always work for every design. You might try just a "createFormBuilder" instead and customize exactly as you need.
public function showQuestionFormAction($ansID, Request $request){
// Get Answers...
$em = $this->getDoctrine()->getManager();
$qb->select('a')
->from('AppBundle:Answer', 'a')
->where('a.answer_id = :ansID')
->setParameter('ansID', $ansID);
$ans = $qb->getQuery()->setMaxResults(1)->getOneOrNullResult();
$form = $this->createFormBuilder()
->add('image') // Not sure what type this is???
->add('question', EntityType::class, array(
'class' => 'AppBundle:Question',
'label' => 'Question:',
'choice_label' => 'question', // Label shown.
'choice_value' => 'question_id', // What data you want returned.
'attr' => array('class' => 'question_id'), // For css styling only, you may not need this.
'data' => $ques->getText(), // This is a method (getter) to get question text.
))
->add('ans1', RadioType::class, array(
'label' => '$ans->getAnswer1()',
'required' => false,
'attr' => array(
'onchange' => "check_answer('ans1')", // Javascript function.
'checked' => true,
),
))
->add('ans2', RadioType::class, array(
'label' => '$ans->getAnswer2()',
'required' => false,
'attr' => array(
'onchange' => "check_answer('ans2')", // Javascript function.
'checked' => false,
),
))
...
Then you can use a simple javascript function like so. I made this quickly, so there may be a better/simpler way to design this.
// script/check_answer.js
function check_answer(id){
var ans1 = document.getElementById("form_ans1");
var ans2 = document.getElementById("form_ans2");
var ans3 = document.getElementById("form_ans3");
var ans4 = document.getElementById("form_ans4");
// Check what is changed.
if(id == 'ans1'){
ans2.checked = false;
ans3.checked = false;
ans4.checked = false;
}
if(id == 'ans2'){
ans1.checked = false;
ans3.checked = false;
ans4.checked = false;
}
...
}
Hope that helps.

Add dropdown to symfony 3 form

I want to add a dropdow field for category in my form in symfony version 3, I have tried to solutions but each one have their own problem
First got all categories and pass them to my view and show them:
Action:
/**
* Creates a new News entity.
*
* #Route("/new", name="news_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$news = new News();
$form = $this->createForm('AppBundle\Form\NewsType', $news);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($news);
$em->flush();
return $this->redirectToRoute('news_show', array('id' => $news->getId()));
}
$em = $this->getDoctrine()->getManager();
$categories = $em->getRepository('AppBundle:Category')->findAll();
return $this->render('news/new.html.twig', array(
'news' => $news,
'form' => $form->createView(),
'categories' => $categories,
));
}
View:
{% extends 'base.html.twig' %}
{% block body %}
<h1>News creation</h1>
{{ form_start(form) }}
<label for="news_content" class="required">Category</label>
<select name="news[categoryId]">
{% for category in categories %}
<option value="{{ category.id }}">{{ category.title }}</option>
{% endfor %}
</select>
{{ form_widget(form) }}
<input class="btn btn-sm btn-success" type="submit" value="Create" />
{{ form_end(form) }}
<ul>
<li>
<a class="label label-sm label-info" href="{{ path('news_index') }}">Back to the list</a>
</li>
</ul>
{% endblock %}
The form is created as I expected but when i want to submit it, it show an validation error as bellow:
This form should not contain extra fields.
second solution that I have tried is to generate the dropdown from my Type, so in NewsType I changed the buildForm function as bellow:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('categoryId', EntityType::class, [
'class' => 'AppBundle:Category',
'choice_label' => 'title',
])
->add('title')
->add('content')
;
}
It this way, the form also have been created nicely but after submit, an database exception returned and said:
An exception occurred while executing 'INSERT INTO news (category_id, title, content) VALUES (?, ?, ?)' with params [{}, "asdf", "asdf"]:
Catchable Fatal Error: Object of class AppBundle\Entity\Category could not be converted to string
It mean that my category_id passed as an object !
What should I do?
BTW, my english is a little weak, please do not put and minus on my post, I had been ban multiple times.
Thanks in advance.
all symfony is trying to do is to find a string representation of the Category object, so it can populate the option fields.
you can solve this in a couple of ways:
In the Category object, you can make a __toString method.
public function __toString() {
return $this->name; // or whatever field you want displayed
}
or
you can tell symfony which field to use as the label for the field. From docs
$builder->add('attending', ChoiceType::class, array(
'choices' => array(
new Status(Status::YES),
new Status(Status::NO),
new Status(Status::MAYBE),
),
'choice_label' => 'displayName', // <-- where this is getDisplayName() on the object.
));

howto handle edit forms with FileType inputs in symfony2

in a symfony2 application a entity Message has a one-to-many relation to documents. Documents represents user uploads. i created a form. I realized two Forms: MessageForm and DocumentForm. DocumentForm lives inside a collection FormField in MessageForm. Uploading and processing files does work.
But if i want to edit the entity Message the Form contains as many empty FileInputs as there are Documents existing. desired behaviour would be:
FileInputs to upload new files
Filename (link) to existing files
Possibility to delete existing files
This should be handled inside the form. Changes should be done when the form is submitted.
How can this be realized?
Solution is to write a custom form type extension. as described on http://symfony.com/doc/2.1/cookbook/form/create_form_type_extension.html.
filetype extension
<?php
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\Util\PropertyPath;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
/**
* Class FileTypeExtension
*
* #see http://symfony.com/doc/2.1/cookbook/form/create_form_type_extension.html
*/
class FileTypeExtension extends AbstractTypeExtension
{
/**
* Returns the name of the type being extended.
*
* #return string The name of the type being extended
*/
public function getExtendedType()
{
return 'file';
}
/**
* Add the image_path option
*
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setOptional(array('file_path', 'file_name'));
}
/**
* Pass the image url to the view
*
* #param FormView $view
* #param FormInterface $form
* #param array $options
*/
public function buildView(FormView $view, FormInterface $form, array $options)
{
if (array_key_exists('file_path', $options)) {
$parentData = $form->getParent()->getData();
if (null !== $parentData) {
$propertyPath = new PropertyPath($options['file_path']);
$fileUrl = $propertyPath->getValue($parentData);
} else {
$fileUrl = null;
}
$view->set('file_url', $fileUrl);
}
if (array_key_exists('file_name', $options)) {
$parentData = $form->getParent()->getData();
if (null !== $parentData) {
$propertyPath = new PropertyPath($options['file_name']);
$fileName = $propertyPath->getValue($parentData);
} else {
$fileName = null;
}
$view->set('file_name', $fileName);
}
}
}
customized file_widget
{% block file_widget %}
{% spaceless %}
{% if file_url is not null %}
<div>{{ file_name }}</div>
<div style="display:none">{{ block('form_widget') }}</div>
{% else %}
{{ block('form_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
services.yml
parameters:
foobar.file_type_extension.class: Foobar\Form\Extension\FileTypeExtension
services:
foobar.file_type_extension:
class: %replacethis.file_type_extension.class%
tags:
- { name: form.type_extension, alias: file }
inside a formtype
$builder->add('file','file', array(
"label" => "Datei",
"required" => true,
"attr" => array(),
"file_path" => "webPath",
"file_name" => "name"
));
that's it ;)
In addition to the above answere - wich will let you build a file input wich can be rendered as a link (if it has an url) or a field (if it doesn't) - you might take a look at
http://symfony.com/doc/2.0/cookbook/form/form_collections.html
Wich in conjunction with some jQuery will let you add fields in UI.

Categories