Мой автоматически сгенерированный базовый класс формы выглядит следующим образом:
abstract class BaseGestorForm extends BaseFormDoctrine {
public function setup() {
$this->setWidgets(array(
'persona_fk' => new sfWidgetFormInputHidden(),
'unitat_fk' => new sfWidgetFormInputHidden(),
'baixa' => new sfWidgetFormDateTime(),
));
$this->setValidators(array(
'persona_fk' => new sfValidatorChoice(array('choices' => array($this->getObject()->get('persona_fk')), 'empty_value' => $this->getObject()->get('persona_fk'), 'required' => false)),
'unitat_fk' => new sfValidatorChoice(array('choices' => array($this->getObject()->get('unitat_fk')), 'empty_value' => $this->getObject()->get('unitat_fk'), 'required' => false)),
'baixa' => new sfValidatorDateTime(array('required' => false)),
));
$this->widgetSchema->setNameFormat('gestor[%s]');
$this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
$this->setupInheritance();
parent::setup();
}
public function getModelName() {
return 'Gestor';
}
}
В форму я добавил два дополнительных поля (totes_unitats
и unitats_a_gestionar
). Первое поле представляет собой раскрывающийся список, в котором пользователи выбирают один или несколько вариантов, и с помощью jquery, когда пользователь нажимает кнопку, выбранные параметры добавляются в раскрывающийся список unitats_a_gestionar
. При этом эти опции удаляются из списка totes_unitats
.
class GestorForm extends BaseGestorForm {
public function configure() {
unset($this['baixa']);
$this->widgetSchema['persona_fk'] = new sfWidgetFormChoice(array(
'choices' => UsuariLdap::getAllUsuaris()
));
$this->widgetSchema['totes_unitats'] = new sfWidgetFormChoice(array(
'choices' => UnitatTable::findAllUnitatsPerOrdreArray(),
'multiple' => true
));
$this->widgetSchema['unitats_a_gestionar'] = new sfWidgetFormChoice(array(
'choices' => array(),
'multiple' => true
));
$this->widgetSchema->setLabels(array(
'persona_fk' => 'Gestor',
'unitat_fk' => 'Unitat',
'totes_unitats' => 'Totes les unitats',
'unitats_a_gestionar' => 'Unitats a gestionar'
));
$this->validatorSchema->setOption('allow_extra_fields', true);
$this->validatorSchema['persona_fk'] = new sfValidatorString(array('required' => true), array('required' => 'Requerit'));
}
}
Где я нахожу проблему, так это в файле действий. Прежде всего, я вызываю метод executeNouGestor
, который отрисовывает форму. Затем, когда пользователь нажимает кнопку «Продолжить» и создает объект Gestor, он вызывает executeValidaGestor
, который проверяет форму. Этот последний метод вызывает processFormGestor
, где нет возможности получить дополнительное поле unitats_a_gestionar
.
public function executeNouGestor(sfWebRequest $request) {
$this->gestorForm = new GestorForm();
}
public function executeValidaGestor(sfWebRequest $request) {
$this->forward404Unless($request->isMethod(sfRequest::POST));
$this->gestorForm = new GestorForm();
$this->processFormGestor($request, $this->gestorForm);
$this->setTemplate('nouGestor');
}
protected function processFormGestor(sfWebRequest $request, sfForm $gestorForm) {
$gestorForm->bind($request->getParameter($gestorForm->getName()), $request->getFiles($gestorForm->getName()));
if ($gestorForm->isValid()) {
var_dump($_POST);
var_dump($request->getParameterHolder()->getAll());
...
}
}
Эти два var_dump показывают мне следующую информацию:
var_dump($_POST):
array(2) {
["gestor"]=>
array(2) {
["persona_fk"]=>
string(3) "330"
["_csrf_token"]=>
string(32) "91e18aa0570bfc7558d21ebb4b98f512"
}
["Desar"]=>
string(5) "Desar"
}
var_dump($request->getParameterHolder()->getAll()):
array(4) {
["gestor"]=>
array(2) {
["persona_fk"]=>
string(3) "330"
["_csrf_token"]=>
string(32) "91e18aa0570bfc7558d21ebb4b98f512"
}
["Desar"]=>
string(5) "Desar"
["module"]=>
string(13) "administracio"
["action"]=>
string(12) "validaGestor"
}
Итак, как видите, в ["gestor"]
нет трека ни totes_unitats
, ни unitats_a_gestionar
дополнительных полей формы. Понятия не имею почему. Я показываю поля формы в шаблоне как обычно:
<?php echo $gestorForm['persona_fk']->renderLabel(); ?>
<div class="input"><?php echo $gestorForm['persona_fk']->render(); ?></div>
<div class="error-input"><?php echo $gestorForm['persona_fk']->renderError(); ?></div>
<?php echo $gestorForm['totes_unitats']->renderLabel(); ?>
<div class="input multiple"><?php echo $gestorForm['totes_unitats']->render(); ?></div>
<div class="error-input"><?php echo $gestorForm['totes_unitats']->renderError(); ?></div>
<?php echo $gestorForm['unitats_a_gestionar']->renderLabel(); ?>
<div class="input multiple"><?php echo $gestorForm['unitats_a_gestionar']->render(); ?></div>
<div class="error-input"><?php echo $gestorForm['unitats_a_gestionar']->renderError(); ?></div>
Я также добавляю код jquery, который управляет добавленными или удаленными параметрами между двумя раскрывающимися списками с множественным выбором:
function afegirTreureUnitats() {
var boto_afegir = $("#btn-multiple-afegir");
var boto_treure = $("#btn-multiple-treure");
boto_afegir.click(function() {
var selectedItems = $("#gestor_totes_unitats option:selected");
var output = [];
$.each(selectedItems, function(key, e)
{
output.push('<option value="' + e.value + '">' + e.text + '</option>');
});
$("#gestor_unitats_a_gestionar").append(output.join(""));
ordenaOptionsSelect("gestor_unitats_a_gestionar");
selectedItems.remove();
});
boto_treure.click(function() {
var selectedItems = $("#gestor_unitats_a_gestionar option:selected");
var output = [];
$.each(selectedItems, function(key, e)
{
output.push('<option value="' + e.value + '">' + e.text + '</option>');
});
$("#gestor_totes_unitats").append(output.join(""));
ordenaOptionsSelect("gestor_totes_unitats");
selectedItems.remove();
});
}
function ordenaOptionsSelect(idSelect)
{
var options = $('#' + idSelect + ' option');
options.sort(function(a, b)
{
if (a.text > b.text)
return 1;
else if (a.text < b.text)
return -1;
else
return 0;
});
$('#' + idSelect).empty().append(options);
}
$(document).ready(function() {
afegirTreureUnitats();
});
Отображаемая форма имеет следующий вид:
https://drive.google.com/file/d/0B0Mz720p9Q_DN1RnYWIyR0pXOTQ/edit?usp=sharing
Я также обнаружил любопытный факт. Если я выбираю один из вариантов в раскрывающемся списке, либо totes_unitats
, либо unitats_a_gestionar
, они отправляются методом POST, но только один (если я выбираю более одного, я могу получить только один из выбранных вариантов).