Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the same Symfony 2 form for edit & delete (differences in fields)

Tags:

forms

symfony

Currently I have a form

class Project extends AbstractType {
    public function buildForm(FormBuilder $builder, array $options) {
        $builder->add('name');
        $builder->add('description', 'textarea');
        $builder->add('iconFile', 'file', array('label' => 'Icon', 'required' => false));
    }
    // ...
}

I am using for edit & delete fine so far. But now, in the edit "mode", I want to allow the user to clear the icon for the project. I think I can add a radio button, but I will need it to be "inactive" in the add mode. For now I am handling the image upload in my model, and I'd hope to have it there (unless theres a better place to do it)

/**
 * If isDirty && iconFile is null: deletes old icon (if any). 
 * Else, replace/upload icon
 * 
 * @ORM\PrePersist 
 * @ORM\PreUpdate
 */
public function updateIcon() {

    $oldIcon = $this->iconUrl;

    if ($this->isDirty && $this->iconFile == null) {

        if (!empty($oldIcon) && file_exists(APP_ROOT . '/uploads/' . $oldIcon)) 
            unlink($oldIcon);

    } else {

        // exit if not dirty | not valid
        if (!$this->isDirty || !$this->iconFile->isValid())
            return;

        // guess the extension
        $ext = $this->iconFile->guessExtension();
        if (!$ext) 
            $ext = 'png';

        // upload the icon (new name will be "proj_{id}_{time}.{ext}")
        $newIcon = sprintf('proj_%d_%d.%s', $this->id, time(), $ext);
        $this->iconFile->move(APP_ROOT . '/uploads/', $newIcon);

        // set icon with path to icon (relative to app root)
        $this->iconUrl = $newIcon;

        // delete the old file if any
        if (file_exists(APP_ROOT . '/uploads/' . $oldIcon) 
            && is_file(APP_ROOT . '/uploads/' . $oldIcon)) 
            unlink($oldIcon);

        // cleanup
        unset($this->iconFile);
        $this->isDirty = false;
    }

}
like image 270
Jiew Meng Avatar asked May 08 '12 12:05

Jiew Meng


People also ask

How do I modify a Symfony form based on product data?

To do this, you can rely on Symfony’s EventDispatcher component system to analyze the data on the object and modify the form based on the Product object’s data. In this article, you’ll learn how to add this level of flexibility to your forms.

What is the recommended workflow when working with Symfony forms?

The recommended workflow when working with Symfony forms is the following: Build the form in a Symfony controller or using a dedicated form class; Render the form in a template so the user can edit and submit it; Process the form to validate the submitted data, transform it into PHP data and do something with it (e.g. persist it in a database).

How does Symfony fill in the fields of a form?

First, when Symfony renders the form, it calls the getter methods on that Article object and uses those values to fill in the values for the fields. Heck, we can see this immediately!

Can I create my own Symfony form theme?

You can also create your own Symfony form theme. In addition to form themes, Symfony allows you to customize the way fields are rendered with multiple functions to render each field part separately (widgets, labels, errors, help messages, etc.)


2 Answers

You can put conditions during the form build using data:

class Project extends AbstractType {
    public function buildForm(FormBuilder $builder, array $options) {
        $builder->add('name');
        $builder->add('description', 'textarea');
        $builder->add('iconFile', 'file', array('label' => 'Icon', 'required' => false));

        if ($builder->getData()->isNew()) { // or !getId()
            $builder->add('delete', 'checkbox'); // or whatever
        }
    }
    // ...
}
like image 93
Florian Klein Avatar answered Oct 11 '22 18:10

Florian Klein


You can use form events, there is a recipe just for something like that:

http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html

like image 33
Fran Avatar answered Oct 11 '22 16:10

Fran