具有两个字段的 Symfony FormBuilder CollectionType
Symfony FormBuilder CollectionType with two fields
目标:用户可以使用一种形式添加多个实体。每个实体都有两个字段。在这种情况下:条形码和价值。
问题:提交表单时得到一个空数组。
单个实体的 Formbuilder
NewBarcodeForm
class NewBarcodeForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('barcode')
->add('value')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Barcode'
]);
}
public function getBlockPrefix()
{
return 'app_bundle_new_barcode_form';
}
}
条形码列表的 Formbuilder
NewBarcodesForm
class NewBarcodesForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('barcodes', CollectionType::class, array(
'entry_type' => NewBarcodeForm::class,
'allow_add' => true,
)
);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getBlockPrefix()
{
return 'app_bundle_new_barcodes_form';
}
}
控制者
$form = $this->createForm(NewBarcodesForm::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$barcodes = $form->getData();
dump($barcodes);
return $this->render('items/newBarcode.html.twig', [
'barcodesForm' => $form->createView()
]);
HTML表格
<form name="app_bundle_new_barcodes_form" method="post">
<input type="hidden" id="app_bundle_new_barcodes_form__token" name="app_bundle_new_barcodes_form[_token]" value="SFl1xlewaLE1JgGVX5oDc_T1PRSc0-aIUgPSaRLfLSU">
<div>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th> Barcode </th>
<th> Value </th>
</tr>
</thead>
<tbody id="barcodeTable">
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_0_barcode" name="barcodesForm[barcodes][0][barcode]" required="required" class="form-control" value="1111">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_0_value" name="barcodesForm[barcodes][0][value]" required="required" class="form-control" value="1">
</td>
</tr>
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_1_barcode" name="barcodesForm[barcodes][1][barcode]" required="required" class="form-control" value="2222">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_1_value" name="barcodesForm[barcodes][1][value]" required="required" class="form-control" value="22">
</td>
</tr>
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_2_barcode" name="barcodesForm[barcodes][2][barcode]" required="required" class="form-control" value="3333">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_2_value" name="barcodesForm[barcodes][2][value]" required="required" class="form-control" value="333">
</td>
</tr>
</table>
</div>
<button type="submit">Speichern</button>
</form>
转储结果
array:1 [▼ "barcodes" => [] ]
编辑
上面的HTML是twig文件的简化结果,添加了3个条形码后。原始树枝文件如下所示:
{% block body %}
<div id="popDiv" class="ontop">
<div class="panel panel-info" id="popup">
<div class="panel-heading">
<h3 class="panel-title">Barcode-Erfassung gestartet.</h3>
</div>
<div class="panel-body">
{{ form_start(barcodesForm) }}
{{ form_row(barcodesForm._token) }}
<div>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th> Barcode </th>
<th> Anzahl </th>
</tr>
</thead>
<tbody id="barcodeTable">
</tbody>
</table>
</div>
<div class="alert alert-danger" id="barcodeError" style="display: none">
<strong>Fehler!</strong> Der Barcode ist bereits in der Liste.
</div>
<button type="submit" class="btn default blue-stripe pull-right" onClick="hide('popDiv')">Speichern</button>
<button class="btn default pull-right" style="margin-right: 10px" onClick="hide('popDiv')">Abbrechen</button>
{{ form_end(barcodesForm, {'render_rest': false}) }}
<!-- TODO: Abbrechen -->
</div>
</div>
</div>
<button class="btn default" onClick="pop('popDiv')">Click here to open a popup div</button>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script type="text/javascript" src="{{ asset('plugins/jquery.scannerdetection.js') }}"></script>
<script type="text/javascript">
var barcodes = [];
i = 0;
function scan() {
$(document).scannerDetection({
timeBeforeScanTest: 200, // wait for the next character for upto 200ms
startChar: [120], // Prefix character for the cabled scanner (OPL6845R)
endChar: [13], // be sure the scan is complete if key 13 (enter) is detected
avgTimeByChar: 40, // it's not a barcode if a character takes longer than 40ms
onComplete: function(barcode, qty){
if(barcodes.indexOf(barcode) === -1){
document.getElementById('barcodeError').style.display = 'none';
barcodes.push(barcode);
var tr = document.createElement('tr');
tr.innerHTML = '' +
'<td class="col-md-10"><input type="text" id="barcodesForm_barcodes_'+i+'_barcode" name="barcodesForm[barcodes]['+i+'][barcode]" required="required" class="form-control" value="'+ barcode +'"></td>' +
'<td class="col-md-2"><input type="number" id="barcodesForm_barcodes_'+i+'_value" name="barcodesForm[barcodes]['+i+'][value]" required="required" class="form-control" value="1"></td>'
;
i++;
document.getElementById('barcodeTable').appendChild(tr);
}else{
document.getElementById('barcodeError').style.display = 'block';
}
}
});
}
function pop(div) {
document.getElementById(div).style.display = 'block';
scan();
}
function hide(div) {
document.getElementById(div).style.display = 'none';
$(document).scannerDetection(false);
}
</script>
{% endblock %}
表格中的名称错误将barcodesForm
替换为app_bundle_new_barcodes_form
当前表单输入:
<input type="text" id="barcodesForm_barcodes_0_barcode" name="barcodesForm[barcodes][0][barcode]" required="required" class="form-control" value="1111">
<input type="number" id="barcodesForm_barcodes_0_value" name="barcodesForm[barcodes][0][value]" required="required" class="form-control" value="1">
应该是:
<input type="text" id="barcodesForm_barcodes_0_barcode" name="app_bundle_new_barcodes_form[barcodes][0][barcode]" required="required" class="form-control" value="1111">
<input type="number" id="barcodesForm_barcodes_0_value" name="app_bundle_new_barcodes_form[barcodes][0][value]" required="required" class="form-control" value="1">
目标:用户可以使用一种形式添加多个实体。每个实体都有两个字段。在这种情况下:条形码和价值。
问题:提交表单时得到一个空数组。
单个实体的 Formbuilder
NewBarcodeForm
class NewBarcodeForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('barcode')
->add('value')
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'AppBundle\Entity\Barcode'
]);
}
public function getBlockPrefix()
{
return 'app_bundle_new_barcode_form';
}
}
条形码列表的 Formbuilder
NewBarcodesForm
class NewBarcodesForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('barcodes', CollectionType::class, array(
'entry_type' => NewBarcodeForm::class,
'allow_add' => true,
)
);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getBlockPrefix()
{
return 'app_bundle_new_barcodes_form';
}
}
控制者
$form = $this->createForm(NewBarcodesForm::class);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$barcodes = $form->getData();
dump($barcodes);
return $this->render('items/newBarcode.html.twig', [
'barcodesForm' => $form->createView()
]);
HTML表格
<form name="app_bundle_new_barcodes_form" method="post">
<input type="hidden" id="app_bundle_new_barcodes_form__token" name="app_bundle_new_barcodes_form[_token]" value="SFl1xlewaLE1JgGVX5oDc_T1PRSc0-aIUgPSaRLfLSU">
<div>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th> Barcode </th>
<th> Value </th>
</tr>
</thead>
<tbody id="barcodeTable">
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_0_barcode" name="barcodesForm[barcodes][0][barcode]" required="required" class="form-control" value="1111">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_0_value" name="barcodesForm[barcodes][0][value]" required="required" class="form-control" value="1">
</td>
</tr>
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_1_barcode" name="barcodesForm[barcodes][1][barcode]" required="required" class="form-control" value="2222">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_1_value" name="barcodesForm[barcodes][1][value]" required="required" class="form-control" value="22">
</td>
</tr>
<tr>
<td class="col-md-10">
<input type="text" id="barcodesForm_barcodes_2_barcode" name="barcodesForm[barcodes][2][barcode]" required="required" class="form-control" value="3333">
</td>
<td class="col-md-2">
<input type="number" id="barcodesForm_barcodes_2_value" name="barcodesForm[barcodes][2][value]" required="required" class="form-control" value="333">
</td>
</tr>
</table>
</div>
<button type="submit">Speichern</button>
</form>
转储结果
array:1 [▼ "barcodes" => [] ]
编辑
上面的HTML是twig文件的简化结果,添加了3个条形码后。原始树枝文件如下所示:
{% block body %}
<div id="popDiv" class="ontop">
<div class="panel panel-info" id="popup">
<div class="panel-heading">
<h3 class="panel-title">Barcode-Erfassung gestartet.</h3>
</div>
<div class="panel-body">
{{ form_start(barcodesForm) }}
{{ form_row(barcodesForm._token) }}
<div>
<table class="table table-condensed table-hover">
<thead>
<tr>
<th> Barcode </th>
<th> Anzahl </th>
</tr>
</thead>
<tbody id="barcodeTable">
</tbody>
</table>
</div>
<div class="alert alert-danger" id="barcodeError" style="display: none">
<strong>Fehler!</strong> Der Barcode ist bereits in der Liste.
</div>
<button type="submit" class="btn default blue-stripe pull-right" onClick="hide('popDiv')">Speichern</button>
<button class="btn default pull-right" style="margin-right: 10px" onClick="hide('popDiv')">Abbrechen</button>
{{ form_end(barcodesForm, {'render_rest': false}) }}
<!-- TODO: Abbrechen -->
</div>
</div>
</div>
<button class="btn default" onClick="pop('popDiv')">Click here to open a popup div</button>
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script type="text/javascript" src="{{ asset('plugins/jquery.scannerdetection.js') }}"></script>
<script type="text/javascript">
var barcodes = [];
i = 0;
function scan() {
$(document).scannerDetection({
timeBeforeScanTest: 200, // wait for the next character for upto 200ms
startChar: [120], // Prefix character for the cabled scanner (OPL6845R)
endChar: [13], // be sure the scan is complete if key 13 (enter) is detected
avgTimeByChar: 40, // it's not a barcode if a character takes longer than 40ms
onComplete: function(barcode, qty){
if(barcodes.indexOf(barcode) === -1){
document.getElementById('barcodeError').style.display = 'none';
barcodes.push(barcode);
var tr = document.createElement('tr');
tr.innerHTML = '' +
'<td class="col-md-10"><input type="text" id="barcodesForm_barcodes_'+i+'_barcode" name="barcodesForm[barcodes]['+i+'][barcode]" required="required" class="form-control" value="'+ barcode +'"></td>' +
'<td class="col-md-2"><input type="number" id="barcodesForm_barcodes_'+i+'_value" name="barcodesForm[barcodes]['+i+'][value]" required="required" class="form-control" value="1"></td>'
;
i++;
document.getElementById('barcodeTable').appendChild(tr);
}else{
document.getElementById('barcodeError').style.display = 'block';
}
}
});
}
function pop(div) {
document.getElementById(div).style.display = 'block';
scan();
}
function hide(div) {
document.getElementById(div).style.display = 'none';
$(document).scannerDetection(false);
}
</script>
{% endblock %}
表格中的名称错误将barcodesForm
替换为app_bundle_new_barcodes_form
当前表单输入:
<input type="text" id="barcodesForm_barcodes_0_barcode" name="barcodesForm[barcodes][0][barcode]" required="required" class="form-control" value="1111">
<input type="number" id="barcodesForm_barcodes_0_value" name="barcodesForm[barcodes][0][value]" required="required" class="form-control" value="1">
应该是:
<input type="text" id="barcodesForm_barcodes_0_barcode" name="app_bundle_new_barcodes_form[barcodes][0][barcode]" required="required" class="form-control" value="1111">
<input type="number" id="barcodesForm_barcodes_0_value" name="app_bundle_new_barcodes_form[barcodes][0][value]" required="required" class="form-control" value="1">