Monday, August 2, 2010

Delete embed forms/objects in Symfony

First of all, you have to add a delete checkbox to the embedded form:
// lib/form/doctrine/ formclass -> configure()
if ($this->object->exists())
{
   $this->widgetSchema['delete'] = new sfWidgetFormInputCheckbox();
   $this->validatorSchema['delete'] = new sfValidatorPass();
}
Don't forget to echo the 'delete' form widget in the template. Now open the form class which embed the other form. You have to overwrite some basic methods. The code below is used and created by me, but perhaps you won't be able to use/understand. Please, first check the the following blog entry: Embedding Relations in Forms with Symfony 1.3 and Doctrine
public function saveEmbeddedForms($con = null, $forms = null)
 {
  if (null === $forms)
  {
   $notes = $this->getValue('newNotes');
   $forms = $this->embeddedForms;
   foreach ($this->embeddedForms['newNotes'] as $name => $form)
   {
    if (!isset($notes[$name]))
    {
     unset($forms['newNotes'][$name]);
    }
   }
  }
  
  foreach ($forms as $form)
  {
    if ($form instanceof sfFormObject)
    {
   if (!in_array($form->getObject()->getId(), $this->scheduledForDeletion))
   {
     $form->saveEmbeddedForms($con);
     $form->getObject()->save($con);
   }
    }
    else
    {
   $this->saveEmbeddedForms($con, $form->getEmbeddedForms());
    }
  }


 }
 
  protected function doBind(array $values)
  {   
    if (isset($values['Notes']))
    {
      foreach ($values['Notes'] as $i => $noteValues)
      {
        if (isset($noteValues['delete']) && $noteValues['id'])
        {
          $this->scheduledForDeletion[$i] = $noteValues['id'];
        }
      }
    }
    
    parent::doBind($values);
  }
  
  protected function doUpdateObject($values)
  {
    if (count($this->scheduledForDeletion))
    {
      foreach ($this->scheduledForDeletion as $index => $id)
      {
        unset($values['Notes'][$index]);
        unset($this->object['Notes'][$index]);
        Doctrine::getTable('ServiceNote')->find($id)->delete();
      }
    }
 
    $this->getObject()->fromArray($values);
  }

4 comments:

  1. Excelent post, you saved my life today.

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete
  3. Excellent approach. I hope Symfony developers will build in this approach to Symfony ASAP.

    ReplyDelete
  4. Tnx a lot, I have a delete issues a long time ago and I solved that tnx to this post...!!! like AGuSTin said you saved muy life...!!!

    ReplyDelete