WEBアプリケーション研究室 開発ノート TOP

WEBアプリケーション研究室 開発ノート [symfony] sfWidgetFormPropelSelectにoptgroup

スポンサーサイト

-------- --:--

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

    このエントリーをはてなブックマークに追加

まずsfWidgetFormSelectで生成されるselectタグにoptgroupを追加する方法ですが


$choices = array(
'Europe' => array('France' => 'France', 'Spain' => 'Spain', 'Italy' => 'Italy'),
'America' => array('USA' => 'USA', 'Canada' => 'Canada', 'Brazil' => 'Brazil'),
);

$this->widgetSchema['country'] = new sfWidgetFormSelect(array('choices' => $choices));
このようにグループ名をキーにした連想配列をchoicesに渡せば出来ます。
sfWidgetFormPropelSelectはsfWidgetFormSelectの子クラスでchoicesに配列を返すメソッド(getChoices)をセットしてるのでsfWidgetFormPropelSelectを継承したクラスを作ってgetChoicesをオーバーライトしてやれば簡単です。

class sdWidgetFormPropelSelectOptgroup extends sfWidgetFormPropelSelect
{
protected function configure($options = array(), $attributes = array())
{
parent::configure($options, $attributes);
$this->addRequiredOption('optgroup_model');
$this->addOption('optgroup_method', '__toString');
}

public function getChoices()
{
$choices = array();
if (false !== $this->getOption('add_empty'))
{
$choices[''] = true === $this->getOption('add_empty') ? '' : $this->getOption('add_empty');
}

$class = $this->getOption('model').'Peer';

$criteria = is_null($this->getOption('criteria')) ? new Criteria() : clone $this->getOption('criteria');
if ($order = $this->getOption('order_by'))
{
$method = sprintf('add%sOrderByColumn', 0 === strpos(strtoupper($order[1]), 'ASC') ? 'Ascending' : 'Descending');
$criteria->$method(call_user_func(array($class, 'translateFieldName'), $order[0], BasePeer::TYPE_PHPNAME, BasePeer::TYPE_COLNAME));
}

$peer_method = 'doSelectJoin'.$this->getOption('optgroup_model');
$this->checkExistMethod($class, $peer_method);
$objects = call_user_func(array($class, $peer_method), $criteria, $this->getOption('connection'));

$method = $this->getOption('method');
$this->checkExistMethod($this->getOption('model'), $method);

$optgourp_method = $this->getOption('optgroup_method');
$this->checkExistMethod($this->getOption('optgroup_model'), $optgourp_method);

$optgourp_getter = 'get'.$this->getOption('optgroup_model');
$this->checkExistMethod($this->getOption('model'), $optgourp_getter);

foreach ($objects as $object)
{
$optgourp = $object->$optgourp_getter()->$optgourp_method();
$choices[$optgourp][$object->getPrimaryKey()] = $object->$method();
}

return $choices;
}

private function checkExistMethod($class, $method)
{
if (!method_exists($class, $method))
{
throw new RuntimeException(sprintf('Class "%s" must implement a "%s" method to be rendered in a "%s" widget', $class, $method, __CLASS__));
}
}
}
使う時はこんな感じです。

$this->widgetSchema['area'] = new sdWidgetFormPropelSelectOptgroup(array(
'model' => 'Area',
'optgroup_model'=>'MediumArea'
))

optgroup_methodオプションでtoString以外のメソッドを呼び出せます。
並び順は、order_byオプションは複数渡せないようなのでcriteriaにorderをセットしてから渡せばいいと思います。

[symfony 1.1.6]
スポンサーサイト

    このエントリーをはてなブックマークに追加
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。