php - Symfony2: How to use constraints on custom compound form type? -
here question i've been breaking head on while now. please know i'm not symfony2 expert (yet), might have made rookie mistake somewhere.
field1: standard symfony2 text
field type
field2: custom field type compound
field text
field + checkbox
field)
my goal: getting constraints added autovalue
field work on autovalue's text input child
the reason why constraints don't work because notblank
expecting string value , internal data of form field array array('input'=>'value', 'checkbox' => true)
. array value gets transformed string custom datatransformer
. suspect that happens after validating field against known constraints.
as see below in commented code, have been able constraints working on text input, when hardcoded autovalue's form type, , want validate against main field's constraints.
my (simplified) sample code controller , field:
.
controller code
setting quick form testing purposes.
<?php //... // $entityinstance holds entity has it's own constraints // have been added via annotations $formbuilder = $this->createformbuilder( $entityinstance, array( 'attr' => array( // added disable html5 validation 'novalidate' => 'novalidate' ) )); $formbuilder->add('regular_text', 'text', array( 'constraints' => array( new \symfony\component\validator\constraints\notblank() ) )); $formbuilder->add('auto_text', 'textwithautovalue', array( 'constraints' => array( new \symfony\component\validator\constraints\notblank() ) ));
.
textwithautovalue source files
src/my/component/form/type/textwithautovaluetype.php
<?php namespace my\component\form\type; use my\component\form\datatransformer\textwithautovaluetransformer; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; class textwithautovaluetype extends abstracttype { /** * {@inheritdoc} */ public function buildform(formbuilderinterface $builder, array $options) { $builder->add('value', 'text', array( // when uncomment this, notblank constraint works. // want validate against whatever constraints added // main form field 'auto_text' instead of hardcoding them here // 'constraints' => array( // new \symfony\component\validator\constraints\notblank() // ) )); $builder->add('checkbox', 'checkbox', array( )); $builder->addmodeltransformer( new textwithautovaluetransformer() ); } public function getname() { return 'textwithautovalue'; } }
src/my/component/form/datatransformer/textwithautovaluetype.php
<?php namespace my\component\form\datatransformer; use symfony\component\form\datatransformerinterface; class textwithautovaluetransformer implements datatransformerinterface { /** * @inheritdoc */ public function transform($value) { return array( 'value' => (string) $value, 'checkbox' => true ); } /** * @inheritdoc */ public function reversetransform($value) { return $value['value']; } }
src/my/componentbundle/resources/config/services.yml
parameters: services: my_component.form.type.textwithautovalue: class: my\component\form\type\textwithautovaluetype tags: - { name: form.type, alias: textwithautovalue }
src/my/componentbundle/resources/views/form/fields.html.twig
{% block textwithautovalue_widget %} {% spaceless %} {{ form_widget(form.value) }} {{ form_widget(form.checkbox) }} <label for="{{ form.checkbox.vars.id}}">use default value</label> {% endspaceless %} {% endblock %}
.
question
i have been reading docs , google quite hours , can't figure out how copy, bind, or reference original constraints have been added while building form.
-> know how accomplish this?
-> bonus points; how enable constraints have been added main form's bound entity? (via annotations on entity class)
ps
sorry became such long question, hope succeeded in making issue clear. if not, please ask me more details!
i suggest read again documentation validation first.
what can make out of validation occurs on classes rather form types. overlooked. need is:
- to create data class textwithautovaluetype, called src/my/bundle/form/model/textwithautovalue instance. must contain properties called text , checkbox , setters/getters;
- to associate data class form type. this, must create textwithautovaluetype::getdefaultoptions() method , populate data_class option. go here more info method;
- create validation data class. can either use annotations or resources/config/validation.yml file this. instead of associating constraints fields of form, must associate them properties of class:
validation.yml:
src/my/bundle/form/model/textwithautovalue: properties: text: - type: type: string - notblank: ~ checkbox: - type: type: boolean
edit:
i assume know how use form type in another. when defining validation configuration, can use useful something, called validation groups. here basic example (in validation.yml file, since i'm not proficient validation annotations):
src/my/bundle/form/model/textwithautovalue: properties: text: - type: type: string groups: [ default, create, edit ] - notblank: groups: [ edit ] checkbox: - type: type: boolean
there groups parameter can added every constraint. array containing validation group names. when requesting validation on object, can specify set of groups want validate. system in validation file constraints should applied.
by default, "default" group set on constraints. group used when performing regular validation.
- you can specify default groups of specific form type in myformtype::getdefaultoptions(), setting validation_groups parameter (an array of strings - names of validation groups),
- when appending form type another, in myformtype::buildform(), can use specific validation groups.
this, of course, standard behaviour form type options. example:
$formbuilder->add('auto_text', 'textwithautovalue', array( 'label' => 'my_label', 'validation_groups' => array('default', 'edit'), ));
as use of different entities, can pile data classes following same architecture piled-up forms. in example above, form type using textwithautovaluetype have have data_class has 'auto_text' property , corresponding getter/setter.
in validation file, valid constraints able cascade validation. property valid detect class of property , try find corresponding validation configuration class, , apply same validation groups:
src/my/bundle/form/model/containerdataclass: properties: auto_text: valid: ~ # call validation conf below same groups src/my/bundle/form/model/textwithautovalue: properties: ... etc
Comments
Post a Comment