понедельник, марта 23, 2009

Группировка виджетов(sfWidget) в админ генераторе(admin-generator) для symfony 1.2

Сегодня мне понадобилось динамически стороить элементы формы в админ генераторе и группировать их.
Это оказалось не столь простой задачей.
Я использую symfony 1.2.5-DEV из svn.
Сразу оговорюсь, что строить из embedded forms я не хочу, т.к. элементы динамические.
Вот мои действия. Постоим простейший вариант:

$this->widgetSchema['group0'] = new sfWidgetFormSchema(array(
'name0' => new sfWidgetFormInput(),
'email0' => new sfWidgetFormInput(),
));

сгенерированный html код будет:

<div>
<label for="t_object_key_group0">Group0</label>
<label for="t_object_key_group0_name0">Name0</label>
<input name="t_object_key[group0][name0]" id="t_object_key_group0_name0" type="text">
<label for="t_object_key_group0_email0">Email0</label>
<input name="t_object_key[group0][email0]"id="t_object_key_group0_email0" type="text">
</div>




Смотрится - не очень. Тогда покопавшись в коде я попробовал указать FormFormatter:

$decorator = new sfWidgetFormSchemaFormatterTable($this->widgetSchema
['group0']);
$this->widgetSchema['group0']->addFormFormatter('custom', $decorator);
$this->widgetSchema['group0']->setFormFormatterName('custom');


Эффект тот же.
Тогда я использовал RowFormat:

$this->widgetSchema['group0']->getFormFormatter()->setRowFormat
("\n<table> <th>%label%</th>\n <td>%error%%field%%help%
%hidden_fields
%</td>\n</tr></table>");


сгенерированный html код будет:

<div>
<label for="t_object_key_group0">Group0</label>
<table> <tbody><tr><th><label for="t_object_key_group0_name0"
>Name0</label></th>
<td><input name="t_object_key[group0][name0]"id="t_object_key_group0_name0" type="text"></td>
</tr></tbody></table>
<table> <tbody><tr><th><label
for="t_object_key_group0_email0">Email0</label></th>
<td><input name="t_object_key[group0][email0]" id="t_object_key_group0_email0" type="text"></td>
</tr></tbody></table>
</div>




Тоже не то что я ожидал.
И выходом из всего этого будет:

$this->widgetSchema['group0'] = new sfWidgetFormSchema(array(
'grouped' => new sfWidgetFormSchema(array(
'name0' => new sfWidgetFormInput(),
'email0' => new sfWidgetFormInput(),
))
));
$this->widgetSchema['group0']->getFormFormatter()->setRowFormat
("\n<table> <th>%label%</th>\n <td>%error%%field%%help%
%hidden_fields
%</td>\n</tr></table>");



сгенерированный html код будет:

<div>
<label for="t_object_key_group0">Group0</label>
<table> <tbody><tr><th>Grouped</th>
<td></td></tr><tr>
<th><label for="t_object_key_group0_grouped_name0">Name0</label></th>
<td><input name="t_object_key[group0][grouped][name0]"
id="t_object_key_group0_grouped_name0" type="text"></td>
</tr>
<tr>
<th><label for="t_object_key_group0_grouped_email0">Email0</label></
th>
<td><input name="t_object_key[group0][grouped][email0]"
id="t_object_key_group0_grouped_email0" type="text"></td>
</tr>
</tbody></table>
</div>




Это и есть то что нам надо.
Похоже на то, что setFormFormatterName работает только с embedded forms.
Я пытался попросить объяснений это на гугл групс, но без результатно.

Теперь самое интересное. Как же будет выглядеть валидатор:

$this->validatorSchema['group0'] = new sfValidatorSchema(array(
'grouped' => new sfValidatorSchema(array(
'name0' => new sfValidatorInteger(),
'email0' => new sfValidatorString(),
))
));


Таким образом используя sfWidgetFormSchema можно делать сгруппированные формы любой вложенности.

Комментариев нет: