Checking which form field value has changed Symfony 3

7.1k views Asked by At

I need to check inside the FormType which field has changed. Is there any method to do it? I've searched for a while, then tried to get edited entities field in few ways (with form events too) to catch the edited fields, but no simple result.

Is there any way to do it easy, or I need to be more creative in making such thing? The best it would be, if I can get an example with entity type, but any clue would be great.

P.S. I cant do it on client-side - I must do it on server side for particular reason.

2

There are 2 answers

0
Rallyholic On BEST ANSWER

Done with this: https://stackoverflow.com/a/33923626/8732955

Suppose we want to check the "status" field in our ImportantObject, code needs to look like that

if($form->isSubmitted() && $form->isValid())
{
        $uow = $em->getUnitOfWork();
        $uow->computeChangeSets();
        $changeSet = $uow->getEntityChangeSet($importantObject);

        if(isset($changeSet['status'])){
          //do something with that knowledge
        }
}
0
dapeyo On

Old post but interesting question.

How I solved it to check a relation between entities but it also works for a single field value. Easier than dealing with doctrine listeners.

Imagine you have a user with multiple tags and a form with checkboxes to add or remove tags

In the controller, create a new variable that contains the value to monitor :

$oldValue = '';
foreach ( $user->getTags() as $tag )
  $oldValue .= $tag->getId().";";

Give it to the formType as an option

$form = $this->get('form.factory')->create(userType::class, $user,
      ['oldValue' => $oldValue ]);

In the formType, create an hidden field

use Symfony\Component\Form\Extension\Core\Type\HiddenType;

public function buildForm(FormBuilderInterface $builder, array $options)
    ....
    $oldValue = $options['oldValue'];
    $builder         
      ->add('oldValue', HiddenType::class, [
          'data'          => $oldValue,
          'mapped'        => false,
      ]);

...

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class'        => 'pathToEntity',          
        'oldValue'          => null,
    ));
}

Back in the controller get your old field value :

if ( $form->isSubmitted() && $form->isValid() )
{
  // Stuff
  $em->flush();
  //  Check changes :
  $oldValue = $form->get('oldValue')->getData();
  $oldValues = explode(';', $oldValue);
  $newValues = $user->getTags();

Compare arrays and finish the stuff...