Reputation: 1183
My EntryAdmin form needs three or four extra fields for different Campaigns defined by users and handled via entity CampaignProperties then appended via ajax dynamically when corresponding radio button is checked.
I have an EntryProperty table which then should store entry_id, property_id and value.
My intention was to save the extra fields on Entry entity's postPersist event.
I have extended the edit.html.twig which appends fields on the form fine but now I'm stuck when it comes to persisting as extra fields throw the error 'This form should not contain extra fields.'.
Here is the code: EntryAdmin form section
$formMapper
->add('channel', 'choice', array('attr' => array('class' => 'channels'), 'expanded' => true, 'choices' => $this->getConfigurationPool()->getContainer()->get('doctrine')->getRepository('AcmeMyBundle:Entry')->allowedChannels($security_context))) /* checks user-allowed campaigns to load extra campaign fields on check */
->add('name')
->add('tel', null, array('label' => 'Telephone'))
->add('email')
->add('deviceType', 'choice', array('expanded' => true, 'choices' => array('Smartphone', 'Feature phone')))
->add('createdAt', 'sonata_type_datetime_picker', array('label' => 'Posted on'))
->with('Items for sale')
->add('listings','sonata_type_collection', array(
// Prevents the "Delete" option from being displayed
'type_options' => array('delete' => false)
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
))
->end()
->with('Photos')
->add('images','sonata_type_collection', array(
// Prevents the "Delete" option from being displayed
'type_options' => array('delete' => false)
), array(
'edit' => 'inline',
'inline' => 'table',
'sortable' => 'position',
))
->end()
;
Extra fields twig loaded via ajax.
{% block fields %}
{% if(channel.properties) %}
<div class="box box-success">
<div class="box-header">
<h4 class="box-title">
Additional information
</h4>
</div>
<div class="box-body">
<div class="sonata-ba-collapsed-fields">
{% for property in channel.properties %}
<div id="sonata-ba-field-container-{{ uniqId }}_{{ property.name }}" class="form-group">
<label for="{{ uniqId }}['properties'][{{ property.id }}]" class="control-label required">
{{ property.label }}
</label>
<div class=" sonata-ba-field sonata-ba-field-standard-natural">
{% if(property.type == 'Text') and (property.length < 255) or (property.type == 'Number') %}
<input type="text" class=" form-control" maxlength="255" required="required" name="{{ uniqId }}['properties'][{{ property.id }}]" id="{{ uniqId }}_{{ property.name }}">
{% endif %}
{% if(property.type == 'Text') and (property.length > 255) %}
<textarea class="form-control" required="required" name="{{ uniqId }}['properties'][{{ property.id }}]" id="{{ uniqId }}_{{ property.name }}"></textarea>
{% endif %}
{% if(property.type == 'Boolean') %}
<ul class="list-unstyled channels" id="{{ uniqId}}_properties_{{ property.name }}">
<li>
<label class="">
<div class="iradio_minimal" style="position: relative;" aria-checked="false" aria-disabled="false">
<input type="radio" value="0" required="required" name="{{ uniqId }}['properties'][{{ property.id }}]" id="{{ uniqId}}_properties_{{ property.name }}_0" style="position: absolute; opacity: 0;">
<ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 0px none; opacity: 0;"></ins>
</div>
<span>No </span>
</label>
</li>
<li>
<label class="">
<div class="iradio_minimal" style="position: relative;" aria-checked="false" aria-disabled="false">
<input type="radio" value="1" required="required" name="{{ uniqId }}['properties'][{{ property.id }}]" id="{{ uniqId}}_properties_{{ property.name }}_1" style="position: absolute; opacity: 0;">
<ins class="iCheck-helper" style="position: absolute; top: 0%; left: 0%; display: block; width: 100%; height: 100%; margin: 0px; padding: 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255); border: 0px none; opacity: 0;"></ins>
</div>
<span>Yes </span>
</label>
</li>
</ul>
{% endif %}
{% if(property.type == 'Date') %}
<div class="form-group">
<div class='input-group date' id='{{ uniqId}}_properties_{{ property.name }}_div' data-date-format="YYYY-MM-DD HH:mm">
<input type="text" class="sonata-medium-date form-control" name="{{ uniqId }}['properties'][{{ property.id }}]" id="{{ uniqId}}_properties_{{ property.name }}" />
<span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<script type="text/javascript">
jQuery(function ($) {
$('#{{ uniqId}}_properties_{{ property.name }}_div').datetimepicker();
});
</script>
{% endif %}
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endblock %}
Anyone with a idea how to solve this?
Upvotes: 0
Views: 5417
Reputation: 1890
I think this covers your issue
$builder->add('tags', 'collection', array(
'type' => new TagType(),
'allow_add' => true, <-- This Bit
));
Going by the updated Symfony 3.1 documentation you'd probably need something like this instead:
$builder->add('tags', CollectionType::class, array(
'entry_type' => TagType::class,
'allow_add' => true,
));
Upvotes: 1