3

我有一个带有特定选择小部件(DoctrineChoice)的表单。选项引用服务器中的某些图像文件,我使用 expander=true 选项(用于复选框/单选按钮)

有没有办法通过显示每个选项的图像来显示小部件?默认情况下,我只获得数据库中选项的 ID。

使用 firebug,我注意到生成的 HTML 有一个带有每个选项 id 的标签,而且,我设法用某个图像更改了它,所以我猜我需要做的就是更改文本每个选项的标签。即使小部件的“标签”选项只是更改了整个选择的标签,所以这不会......

谢谢!

4

1 回答 1

2

好的,经过大量研究,我已经找到了某种解决方案,但也许还有更正确的方法?

我没有使用 sfWidgetFormDoctrineChoice,而是使用了 sfWidgetFormSelectRadio(但 Checkbox 也可以,但我不知道它是否可以与其他小部件一起使用,甚至也可以选择小部件:/ 只是因为我的业务规则需要它,所以 SelectRadio 就足够了在这种特殊情况下......)

小部件的选择选项填充了上一个查询的结果,我用来填充上一个 DoctrineChoice 小部件,之前已处理,因此每条记录的 Id 是每个选择的键和值:

$imgs = Doctrine_Core::getTable('ProjImages')->getImages();
$choices = array('' => '');
foreach ($imgs as $img):
  $choices[$img->getId()] = $img->getId();
endforeach;

接下来,我还将“格式化程序”选项传递给小部件:

$this->widgetSchema['img'] = new sfWidgetFormSelectRadio(array(
                    'choices' => $choices,
                    'formatter' => array($this, 'showAsImages')
                                ));
$this->validatorSchema['img'] = new sfValidatorChoice(array(
                     'choices' => $choices,
                     'required' => false
                     ));

我在验证器中使用了 'required'=>false 选项,因为我还需要在我的小部件中选择“无图像”的选项,这反映在 $choices 数组中作为第一个 ('' => '') 选择。

最后,我编写了格式化程序回调:

public function showAsImages($widget, $inputs)
{
  $rows = array();
  foreach ($inputs as $input)
  {
    $domdoc = new DOMDocument();
    $domdoc->loadHTML($input['label']);
    $node = $domdoc->getElementsByTagName('label')->item(0);
    if ($node->nodeValue != "")
    {
      $img = Doctrine_Core::getTable('ProjImages')->find(array($node->nodeValue));
      $input['label'] = '<label '.$node->attributes->item(0)->name .
                        '="'.$node->attributes->item(0)->value.'">' .
                        '<img src="'.$img->getImg().'" alt="image" />' .
                        '</label>';
    }
    $rows[] = $widget->renderContentTag('li',
                    $input['input'].
                    $widget->getOption('label_separator').
                    $input['label']);
  }
  return $widget->renderContentTag('ul',
                       implode($widget->getOption('separator'), $rows),
                       array('class' => $widget->getOption('class')));
}

我使用了 sfWidgetFormSelectRadio 的原始默认格式化程序的源代码,并在此基础上修改了每个输入元素的“标签”(所有其余代码与我使用的源代码完全相同)。

而对于每个输入元素的标签,我使用了DOMDocument对象来获取值(图片的id),然后做一个DB查询来获取图片,然后用<img>标签重新组装'label' ...当然,如果我碰巧找到空选项,我会使用默认的“标签”...

就是这样......我认为格式化程序回调可以做更多的工作,所以欢迎任何建议,甚至更好的问题解决方案......如您所见,我依赖于“格式化程序”选项小部件,据我所知,只有一些小部件接受此选项...

谢谢阅读!

于 2011-02-24T19:56:33.923 回答