NestedSet 模型的 sfWidgetFormDoctrineChoice

发布于 2024-11-18 12:28:39 字数 1195 浏览 4 评论 0原文

我在为 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 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; ?>

I'm experiencing a difficulty in rendering sfWidgetFormDoctrineChoice (set of checkboxes) widget for a NestedSet structure.

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;
  }
}

Now, if I just render form like this: <?php echo $form['relatedmodel_list'] ?>
It will only display form widgets (checkboxes) for first level elements of my hierarchy.

I am looking for an implementation that will allow me to iterate over widget's choices the way I would iterate over collection:

<?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; ?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

电影里的梦 2024-11-25 12:28:39

我正在使用 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')
  );

I'm using sfWidgetFormTree to display my nestedSet. If you really want to display your tree in a flat way don't use HYDRATE_RECORD_HIERARCHY.

The widget linked is very convinient, you just have to provide a choices array like this :

$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')
  );
月依秋水 2024-11-25 12:28:39

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

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; ?>

If anyone cares, I think I found a wonderful solution which allows you to recursively iterate over checkboxes in template. The idea behind it is that you configure 'relatedmodel_list' widget as a single checkbox and render it many times in your template (while iterating over relatedmodel collection).

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

Checkboxes now have incorrect name and value attributes. This can be fixed very easily:

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);
  }
}

Now we can recursively render our form widget in template:

//_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; ?>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文