好的,经过大量研究,我已经找到了某种解决方案,但也许还有更正确的方法?
我没有使用 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' ...当然,如果我碰巧找到空选项,我会使用默认的“标签”...
就是这样......我认为格式化程序回调可以做更多的工作,所以欢迎任何建议,甚至更好的问题解决方案......如您所见,我依赖于“格式化程序”选项小部件,据我所知,只有一些小部件接受此选项...
谢谢阅读!