Quantcast
Channel: Active questions tagged symfony4 - Stack Overflow
Viewing all articles
Browse latest Browse all 3925

Get initial value of entity in FormExtension

$
0
0

In my update form, I want to add a data attribute on the inputs that will contains the initial value of the entity. This way, I will be able to highlight the input when the user will modify it.

In the end, only the input modified by the users will be highlighted.

I want to use this only in update, not in creation.

To do so, I created a form extension like this:

class IFormTypeExtension extends AbstractTypeExtension{...public static function getExtendedTypes(){    //I want to be able to extend any form type    return [FormType::class];}public function configureOptions(OptionsResolver $resolver){    $resolver->setDefaults(['is_iform' => false,'is_iform_modification' => function (Options $options) {            return $options['is_iform'] ? null : false;        },    ]);    $resolver->setAllowedTypes('is_iform', 'bool');    $resolver->setAllowedTypes('is_iform_modification', ['bool', 'null']);}public function buildView(FormView $view, FormInterface $form, array $options){    if (!$options['is_iform'] && !$this->isParentIForm($form)) {        return;    }    //We need to add the original value in the input as data-attributes    if (is_string($form->getViewData()) || is_int($form->getViewData())) {        $originValue = $form->getViewData();    } elseif (is_array($form->getViewData())) {        if (is_object($form->getNormData())) {            $originValue = implode('###', array_keys($form->getViewData()));        } elseif (is_array($form->getNormData()) && count($form->getNormData()) > 0 && is_object($form->getNormData()[0])) {            $originValue = implode('###', array_keys($form->getViewData()));        } else {            $originValue = implode('###', $form->getViewData());        }    } else {        //There's no value yet        $originValue = '';    }    $view->vars['attr'] = array_merge($view->vars['attr'], ['data-orig-value' => $originValue]);}private function isParentIForm(FormInterface $form){    if (null === $form->getParent()) {        return $form->getConfig()->getOption('is_iform');    }    return $this->isParentIForm($form->getParent());}}

As you can see in the buildView method, I get the originValue from the ViewData.

In a lot of cases, this works well.

But if I have any validation error in my form OR if I reload my form through AJAX, the ViewData contains the new information and not the values of the entity I want to update.

How can I get the values of the original entity?

  1. I don't want to make a DB request in here.
  2. I think I can use the FormEvents::POST_SET_DATA event, then save the entity values in session and use these in the buildView.
  3. I could also give a new Option in my OptionResolver to ask for the initial entity.
  4. Is it possible to have the original data of the entity directly form the buildView? (If I'm not wrong, this means the form before we call the handleRequest method).

Someone wanted to have an example with a controller. I don't think it's really interresting, because with the FormExtension, the code will be added automatically. But anyway, here is how I create a form in my controller :

$form = $this->createForm(CustomerType::class, $customer)->handleRequest($request);

And in the CustomerType, I will add the 'is_iform' key with configureOptions() :

public function configureOptions(OptionsResolver $resolver){    $resolver->setDefaults(["translation_domain" => "customer","data_class" => Customer::class,'is_iform' => true //This line will activate the extension    ]);}

Viewing all articles
Browse latest Browse all 3925

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>