用于NestedSet模型的sfWidgetFormDoctrineChoice

时间:2011-07-04 12:47:19

标签: symfony1 doctrine symfony-1.4 symfony-forms doctrine-1.2

我在为NestedSet结构呈现sfWidgetFormDoctrineChoice(一组复选框)小部件时遇到了困难。

class ModelForm extends BaseModelForm
{
  public function configure()
  {
      $this->setWidget('relatedmodel_list', new sfWidgetFormDoctrineChoice(array(
        'expanded' => true,
        'multiple' => true,
        'model' => 'Relatedmodel',
        'table_method' => 'fetchTree'
      )));
  }
}
class RelatedmodelTable extends Doctrine_Table
{
  /**
   * Gets tree elements in one query (one root only)
   */
  public function fetchTree()
  {
    $q = $this->createQuery('m')
      ->addOrderBy('m.lft');

    $tree = $q->execute(array(),  Doctrine_Core::HYDRATE_RECORD_HIERARCHY);

    return $tree;
  }
}

现在,如果我只是渲染这样的形式:<?php echo $form['relatedmodel_list'] ?> 它将仅显示我的层次结构的第一级元素的表单小部件(复选框)。

我正在寻找一种实现,它允许我按照迭代集合的方式迭代小部件的选择:

<?php foreach ($form['relatedmodel_list'] as $widget): ?>
  <?php echo $widget->render() ?>
  <?php foreach ($widget->getChildren() as $child_widget): ?>
    <?php echo $child_widget->render() ?>
  <?php endforeach; ?>
<?php endforeach; ?>

2 个答案:

答案 0 :(得分:0)

我正在使用sfWidgetFormTree来显示我的nestedSet。如果您真的想以平面方式显示树,请不要使用HYDRATE_RECORD_HIERARCHY。

链接的小部件非常方便,您只需要提供这样的选择数组:

$choices = array(
    1=> array('label'=>'test', 'children'=>array(
      2=> array('label'=>'test2', 'children'=> array(
        3=> array('label'=>'test3'),
        4=> array('label'=>'hans')
      )),
      5=> array('label'=>'wurst')
    )),
    6=>array('label'=>'letzter')
  );

答案 1 :(得分:0)

如果有人关心,我想我找到了一个很棒的解决方案,它允许你递归地迭代模板中的复选框。其背后的想法是将“relatedmodel_list”小部件配置为单个复选框,并在模板中多次呈现(同时迭代相关模型集合)。

class ModelForm extends BaseBookForm
{
  public function configure()
  {
    $this->setWidget('relatedmodel_list', new myWidgetFormInputCheckbox());
  }
}

复选框现在具有不正确的名称和值属性。这很容易解决:

class myWidgetFormInputCheckbox extends sfWidgetFormInputCheckbox
{
  public function render($name, $value = null, $attributes = array(), $errors = array())
  {
    //fix value checking
    if (in_array($attributes['value'], (array)$value))
    {
      $attributes['checked'] = 'checked';
    }
    //fix name for multiple
    $name = $name . "[]";

    return parent::render($name, null, $attributes, $errors);
  }
}

现在我们可以在模板中递归渲染表单小部件:

//_form.php
<ul>
  // Model::getRelatedTree() is proxy to Relatedmodel::fetchTree()
  <?php include_partial('node', array('node' => $form->getObject()->getRelatedTree(), 'form' => $form)) ?>
</ul> 

//_node.php
<?php foreach ($node as $item): ?>
<li>
  <?php echo $form['pages_list']->render(array('value'=>$item->id)) ?>
  <?php echo $form['pages_list']->renderLabel((string)$item) ?>
  <?php if (isset($item['__children']) && count($item['__children']) > 0): ?>
  <ul>
    <?php include_partial('node', array('node' => $item['__children'], 'form' => $form)) ?>
  </ul>
  <?php endif; ?>
</li>
<?php endforeach; ?>