April 2010

Tratando múltiplos telefones com embedded forms no admin generator

No meu post anterior, comentei sobre uma tabela (imovel) que possui diversos telefones (1-N). Nesse post vou tentar explicar como fiz o formulário de edição para tratar os N telefones dos imoveis.

O jeito que fiz vai ficar como a imagem abaixo. Vou deixar sempre 3 campos em branco para adicionar novos telefones. Para remover um telefone, basta deixa-lo em branco (em breve eu crio um botão com ajax para remover).

Vamos começar editando o lib/form/ImovelForm.class.php

class ImovelForm extends BaseImovelForm
{
  public function configure()
  {
      $todoWrapperForm = new sfForm();
      if ($this->getObject()->countTelefoneImovels() > 0) {
          foreach ($this->getObject()->getTelefoneImovels() as $telefone){
             $todoWrapperForm->embedForm(‘tel_’.$telefone->getId(), new TelefoneImovelForm($telefone));
          }
      }
    // adiciona os 3 forms em branco
    $todoWrapperForm->embedForm(‘tel_A’, new TelefoneImovelForm());
    $todoWrapperForm->embedForm(‘tel_B’, new TelefoneImovelForm());
    $todoWrapperForm->embedForm(‘tel_C’, new TelefoneImovelForm());

    $this->embedForm(‘tels’, $todoWrapperForm);

    $this->validatorSchema->setOption(‘filter_extra_fields’, false);
    $this->validatorSchema->setOption(‘allow_extra_fields’, true);

  }

  public function bind(array $taintedValues = null, array $taintedFiles = null) {
    foreach($this->embeddedForms[‘tels’]->getEmbeddedForms() as $key=>$telForm)
    {
       if ($taintedValues[‘tels’][$key][‘telefone’] == "")
       {
          unset($this->embeddedForms[‘tels’]->embeddedForms[$key], $taintedValues[‘tels’][$key]);
          $telForm->getObject()->delete();
       }
    }
    parent::bind($taintedValues, $taintedFiles);
  }

  // http://trac.symfony-project.org/ticket/5842
  public function saveEmbeddedForms($con = null, $forms = null, $taintedValues = null, $taintedFiles = null)
  {
    //atualiza o imovel_id da telefone_imovel depois de ter o imovel salvo
    //http://www.thatsquality.com/articles/embedding-child-forms-with-sfformpropel-a-practical-example
    foreach($this->embeddedForms[‘tels’]->getEmbeddedForms() as $telForm)
    {
       if (!$telForm->getObject()->getImovelId())
       {
         $telForm->getObject()->setImovelId($this->getObject()->getId());
       }
    }

    if (is_null($con))
    {
      $con = $this->getConnection();
    }

    if (is_null($forms))
    {
      $forms = $this->embeddedForms;
    }

    if (is_null($taintedValues))
   {
      $taintedValues = $this->taintedValues;
   }

   if (is_null($taintedFiles))
   {
      $taintedFiles = $this->taintedFiles;
   }

   foreach ($forms as $key => $form)
   {
       // é esse trecho que corrige o problema
       if ($form instanceof sfFormPropel)
       {
          $form->bindAndSave($taintedValues[$key], $taintedFiles);
       } else {
          $this->saveEmbeddedForms($con, $form->getEmbeddedForms(), $taintedValues[$key], $taintedFiles);
       }
   }
 }
}
 

Agora vamos criar um partial para mostrar os telefones no formulário. Crie o arquivo apps/backend/imovel/templates/_tels.php


<div id="embed_tels">
<?php foreach ($form->getEmbeddedForms() as $key => $itemForm) {
             if (substr($key , 0 , 8) == ‘tels’): ?>
                 <div class="sf_admin_form_row sf_admin_text sf_admin_form_field_telefone<?php echo preg_replace("/[^0-9]/", ‘’, $key); //only number ?>">
                    <div>
                       <?php echo $form[$key]; ?>
                    </div>
                 </div>
             <?php endif ?>
<?php } ?>
</div>
 

Depois de ter criado o partial, basta adiciona-lo ao apps/backend/imovel/config/generator.yml


edit:
  display: [_tels, campo1, campo2]
 

É isso.. tive como referência diversos sites, mas principalmente o blog that’s quality.

http://www.thatsquality.com/search?query=embedded

embedded form
form
php
propel

Comments (0)

Permalink

Adicionando um filtro customizado no admin generator (symfony 1.2)

Tenho uma tabela (1-N) que possui diversos telefones relacionados.

config/schema.yml:


imovel:
  id:
  ()
  created_at:

imovel_telefone:
  id:
  imovel_id:
  telefone:   varchar(20)
  created_at:
 

No admin generator, será necessário criar um filtro customizado, porque o telefone não faz parte da tabela imovel. Para isso, vamos alterar o arquivo lib/filter/ImovelFormFilter.class.php


class ImovelFormFilter extends BaseImovelFormFilter
{
  public function configure() {
     $this->widgetSchema[‘telefone’] = new sfWidgetFormInput();
     $this->validatorSchema[‘telefone’] = new sfValidatorPass(array(‘required’ => false));
  }

  public function getFields() {
    return array_merge(array(‘telefone’ => ‘Telefone’), parent::getFields());
  }

  protected function addTelefoneColumnCriteria(Criteria $criteria, $field, $values) {
    $criteria->addJoin(ImovelPeer::ID, TelefoneImovelPeer::IMOVEL_ID, Criteria::LEFT_JOIN);
    $criteria->add(TelefoneImovelPeer::TELEFONE, $values);
  }
}
 

Para finalizar, altere o generator.yml do seu backend e adicione o field telefone.


filter:
  fields:
    display:  [ telefone, campo1, campo2 ]
 

filter
php
symfony

Comments (0)

Permalink