【问题标题】:Double listing not working in Symfony 1.4 embedded form双重列表在 Symfony 1.4 嵌入式表单中不起作用
【发布时间】:2013-05-09 11:30:50
【问题描述】:

我正在努力获得一个在 Symfony 1.4 后端模块中工作的简单表单。

这个想法是创建一个嵌入式表单(一对多关系,Inschrijvingen -> Danser)。每个嵌入的表格都有一对多的关系。 (减)表格正确显示,但不保存减列表。 (多对多关系)

我嵌入的 DanserForm 可以独立工作。但是在将其嵌入 InschrijvingenForm 时不起作用。

我尝试了以下教程。但这对我不起作用:http://inluck.net/Blog/Many-to-many-relations-in-embedded-form-in-Symfony-1_4

我的 schema.yml

Inschrijving:
  actAs:
    Timestampable: ~
  columns:
    voornaam: { type: string(100), notnull: true, minlength: 2 }
    achternaam: { type: string(100), notnull: true, minlength: 2 }
    straat: { type: string(100), notnull: true, minlength: 2 }
    nr: { type: string(5) }
    postcode: { type: int(9), notnull: true, minlength: 4 }
    gemeente: { type: string(100), notnull: true, minlength: 2 }
    land: { type: string(2), notnull: true, default: 'BE' }
    telefoon: { type: string(100), notnull: true, minlength: 8 }
    email:  { type: string(100), notnull: true, minlength: 4, nospace: true }
    gestructureerde_mededeling: { type: string(20) }
    interne_opmerking: { type: string(1000) }
    gebruiker_id: { type: int(9) }
    is_gearchiveerd:  { type: boolean, default:false }
  relations:
    Danser:
      local: id
      foreign: inschrijving_id
      type: many
      onDelete: CASCADE
      foreignAlias: Dansers

Danser:
  columns:
    voornaam: { type: string(100), notnull: true, minlength: 2 }
    achternaam: { type: string(100), notnull: true, minlength: 2 }
    geboortedatum: { type: date(), notnull: true }
    email:  { type: string(100), notnull: true, minlength: 4, nospace: true }
    medische_opmerkingen: { type: string(2000) }
    inschrijving_id: { type: int(9), notnull: true }
    is_verzekering_ok: { type: boolean, default:false }
  relations:
    Inschrijving:
      local: inschrijving_id
      foreign: id
      type: one
      onDelete: CASCADE
      foreignAlias: Inschrijvingen
    Lessen:
      class:              Lessen
      refClass:           LessenVanDanser
      local:              danser_id
      foreign:            lessen_id

LessenVanDanser:
  columns:
    lessen_id:             { primary: true, type: integer }
    danser_id:            { primary: true, type: integer }
  relations:
    Lessen:                { onDelete: CASCADE, local: lessen_id, foreign: id ,class: Lessen}
    Danser:          { onDelete: CASCADE, local: danser_id, foreign: id, class: Danser }

Lessen:
  actAs:
    Timestampable: ~
  columns:
    naam: { type: string(100), notnull: true, minlength: 2 }
    leeftijd_van: { type: string(3) }
    leeftijd_tot: { type: string(3) }
    dag:  { type: enum(),values: ['Maandag','Dinsdag','Woensdag','Donderdag','Vrijdag','Zaterdag'],default: Maandag }
    van: { type: time() }
    tot: { type: time() }
    beschrijving: { type: string(5000) }
    max_aantal_deelnemers: { type: int(9) }    
    lesgever_id: { type: int(9), notnull: true }
    locatie_id: { type: int(9), notnull: true }
    lessenreeks_id: { type: int(9), notnull: true }
  relations:
    Danser:
      class:              Danser
      refClass:           LessenVanDanser
      local:              lessen_id
      foreign:            danser_id

InschrijvingenForm.class.php

<?php
class InschrijvingForm extends BaseInschrijvingForm
{
  public function configure()
  {
      unset(
      $this['created_at'], $this['updated_at'],$this['gestructureerde_mededeling']
      );

      $choices = CountryCodes::get();
      $this->widgetSchema['land'] = new sfWidgetFormChoice(array('choices' => $choices));

      $choice_keys = array();
      foreach ($choices as $choice) {
          $choice_keys = array_merge($choice_keys,array_keys($choice));
      }

      $this->setValidator('land', new sfValidatorChoice(array('choices'=>$choice_keys,'required'=>true)));
      $this->setDefault('land','BE');

      //Many to many relations
      $data = $this->getObject();
      $data_count = @count($_POST['inschrijving']['danser']);
      $data_count = $data_count > 0 ? $data_count:1;

        $subForm = new sfForm();

        for ($i = 0; $i < $data_count; $i++){
            if($data['Danser'][$i]){
                $subForm->embedForm($i, new DanserForm($data['Danser'][$i]));
            }else{
                $subForm->embedForm($i, new DanserForm());
            }
        }
        $this->embedForm('danser', $subForm);
  }

  public function saveEmbeddedForms($con = null, $forms = null) {
        if (null === $forms){
            $en_forms = $this->getEmbeddedForm('danser');

            foreach ($en_forms as $name => $form){
                if ($form instanceof sfFormObject){
                    $form->getObject()->setInschrijvingId($this->getObject()->getId());
                    $form->getObject()->save($con);
                }
            }
        }
          return parent::saveEmbeddedForms($con, $forms);
    }
}

DanserForm.class.php

<?php

/**
 * Danser form.
 *
 * @package    dansschool
 * @subpackage form
 * @author     Ilias Barthelemy
 * @version    SVN: $Id: sfDoctrineFormTemplate.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
 */
class DanserForm extends BaseDanserForm
{
  public function configure()
  {
      unset(
      $this['inschrijving_id']
      );

      $years = range(((int) date('Y'))-70, ((int) date('Y'))-3);
      $years_list = array_combine($years, $years);

      //$this->setWidget('geboortedatum', new sfWidgetFormDate(array('format' => '%day%/%month%/%year%','years' => $years_list)));
      $user = sfContext::getInstance()->getUser();
      $inschrijving = $user->getAttribute( 'dansers_form.inschrijving',null,'admin_module' );

      if(!is_null($inschrijving)){
          $this->widgetSchema['inschrijving_id']->setDefault($inschrijving['inschrijving_id']);
      }

      $this->setWidget('geboortedatum',new sfWidgetFormJQueryDate(array(
        'date_widget' => new sfWidgetFormDate(array('format' => '%day%/%month%/%year%','years' => $years_list))
      )));

      $this->widgetSchema['lessen_list'] = new sfWidgetFormDoctrineChoice(array(
      'multiple' => true,
      'model' => 'Lessen',
      'renderer_class' => 'sfWidgetFormSelectDoubleList',
      'renderer_options' => array(
        'label_unassociated' => 'Beschikbare lessen',
        'label_associated' => 'Actief'
    )));

  }

    public function bind(array $taintedValues = null, array $taintedFiles = null)
    {
        if($this->getObject()->getId()>0){
            $taintedValues['id']=$this->getObject()->getId();
            $this->isNew = false;
        }
        parent::bind($taintedValues, $taintedFiles);
    }
}

【问题讨论】:

    标签: doctrine symfony-1.4


    【解决方案1】:

    lessen_list 是您的 BaseDanserFormBaseInchrijvingForm 类中的一个字段吗? Symfony 通常提供一个小部件来管理多对多关系,就像您在基类中的关系一样。我只是想它会被命名为lessenvandanser_list

    我认为您没有正确嵌入 Danser 表单。尝试类似于我在下面所做的操作,在其中将 Danser 对象分配给 Inschrijving 对象,然后使用这些 Danser 对象实例化嵌入的表单。 我所做的是创建一个新的 DanserCollectionForm 类来处理这个逻辑(见下文)。

    // lib\form\DanserCollectionForm.class.php
    class DanserCollectionForm extends sfForm
    {
        if (!$inschrijving = $this->getOption('inschrijving')) {
            throw new InvalidArgumentException(sprintf("%s must be provided with inschrijving object", get_class($this)));
        }
    
        // Get all danser objects associated with this inschrijving
        $dansers = $inschrijving->getDansers();
    
        // If no dansers, then creat a new danser
        if (!$dansers) {
            $danser = new Danser();
            // Assign the danser to the inschrijving
            $danser->Inschrijving = $inschrijving;
            $dansers = array($danser);
        }
    
        // Embed Danser forms
        foreach ($dansers as $key => $danser) {
            $this->embedForm($key, new DanserForm($danser));
        }
    }
    

    然后在你的 InschrijvingForm 类中

    // lib\form\InschrijvingForm.class.php 
    class InschrijvingForm extends BaseInschrijvingForm
    {
        public function configure()
        {
            unset(
                $this['created_at'],
                $this['updated_at'],
                $this['gestructureerde_mededeling']
            );
    
            $choices = CountryCodes::get();
            $this->widgetSchema['land'] = new sfWidgetFormChoice(array('choices' => $choices));
    
            $choice_keys = array();
            foreach ($choices as $choice) {
                    $choice_keys = array_merge($choice_keys,array_keys($choice));
            }
    
            $this->setValidator('land', new sfValidatorChoice(array('choices' => $choice_keys, 'required' => true)));
            $this->setDefault('land','BE');
    
            $collectionForm = new DanserCollectionForm(null, array('inschrijving' => $this->getObject()));
            $this->embedForm('dansers', $collectionForm);
        }
    
        public function saveEmbeddedForms($con = null, $forms = null)
        {
            if (null === $forms) {
                $dansers = $this->getValue('dansers');
                $forms = $this->embeddedForms;
    
                foreach ($this->embeddedForms['dansers'] as $name => $form) {
                    $deleteDanser = // Put logic of whether to ignore/delete danser forms here
                    if ($deleteDanser) {
                        unset($forms['dansers'][$name]);
                        $form->getObject()->delete();
                    }
                }
            }
    
            return parent::saveEmbeddedForms($con, $forms);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多