Target: The User can add more than one entities with one form. Every entity have two fields. In this Case: Barcode and Value.
Problem: I get an empty array when I submit the form.
The Formbuilder for a single entity
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';
}
}
The Formbuilder for a list of barcodes
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';
}
}
The Controller
$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()
]);
The HTML Form
<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>
Result from dump
array:1 [▼ "barcodes" => [] ]
EDIT
The HTML above is a simplified result of the twig file, after adding 3 barcodes. The original twig file looks like this:
{% 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 %}
In the form the name
attribute is incorrect. Replace barcodesForm
to app_bundle_new_barcodes_form
.
Current form inputs:
<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"
>
Should be:
<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"
>