我自动生成的基本表单类如下:
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'));
}
}
我发现问题出在actions文件中。首先,我调用呈现表单的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($请求 - > 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方法发送的,但只有一个(如果我选择多个选项,我只能选择其中一个选项)选择)。
答案 0 :(得分:1)
当您在表单上使用<select>
元素或<input>
或radio
类型的checkbox
时,只有当字段包含任何内容时,浏览器才会在表单提交时发送其值选择的选项。
<select>
标记中的选项列表不会发送回服务器。只有实际选择的选项的值。
您可以通过两种方式解决问题:
创建一个JS,它将在发送之前修改您的表单,并将选择您列表中的所有项目。通过这种方式,您的表单将发送值,您将能够在服务器端使用它们。
其他选项是添加两个隐藏字段,这些字段将保留选项列表并将这些列表与<select>
字段一起修改。