I created a Custom Constraint ( with help from cookbook ). Everything seems to work as i expected, but now I would like to show the error-message not beneath validated-field but at the top of the form (like general form-errors)
My Constraint Class:
class NotOverlapPreviousRecord extends Constraint
{
//@todo
public $message = '{{ value }} is invalid!';
public function validatedBy()
{
return 'not_overlap_previous_record';
}
public function getTargets()
{
return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
}
}
and its validator class
class NotOverlapPreviousRecordValidator extends ConstraintValidator
{
/**
* @var EntityManager
*/
private $em;
public function __construct(EntityManager $o_entitymanager)
{
$this->em = $o_entitymanager;
}
public function validate($value, Constraint $constraint)
{
/** just for demonstration & testing purpose */
if (true) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $value )
->addViolation();
}
}
}
and the FormType where I use custom constraint:
class QuickTimepatchForm extends AbstractType {
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('timeStart', 'time',
array('label' => 'forms.timepatching.label.starttime',
'html5' => true,
'widget' => 'single_text',
'consatraints' => array(
// MY CUSTOM CONSTRAINT. WORKS WELL, but since a use it on 'timeStart', the error message is also beneath the timeStart field...
new TmAssert\NotOverlapPreviousRecord()
)));
/** ... other fields .... */
}
public function configureOptions(OptionsResolver $resolver)
{
/** ... stuff ... */
}
public function getName()
{
return 'tm_quick_form_timepatch';
}
}
So my question is: Is there a way to somehow modify validate()
method of NotOverlapPreviousRecordValidator
so the error message appears on top of the form and not beneath its field ? If not, is there any other way to achieve my goals ?
IMPORTANT! I do not want (I should not) use this custom Constraint as Annotation. No @TmAssert\NotOverlapPreviousRecord in my Entity.
Now I have this:
which is ok, but i want this:
UPDATE: My current form-twig-tempalte:
{# SETUP! #}
{% form_theme o_form 'bootstrap_3_horizontal_layout.html.twig' %}
{# THE FORM #}
{{ form_start(o_form, {'attr' : {'class' : 'tm-patching-form-inline'}}) }}
<fieldset>
{{ form_errors(o_form) }}
<legend class="tm-{{ o_form.vars.value.getTimetick.getState }}">{{ o_form.vars.value.getTimetick.getState|trans }} :: TIMEPATCH</legend>
<div class="form-group col-lg-9">
<div class="col-lg-6 {% if not o_form.timeStart.vars.valid -%}has-error{%- endif %}">
{{ form_label(o_form.timeStart) }}
{{ form_widget(o_form.timeStart, {'attr' : {'class' : 'tm-timepatch-start'}}) }}
{{ form_errors(o_form.timeStart) }}
</div>
<div class="col-lg-6 {% if not o_form.timeEnd.vars.valid -%}has-error{%- endif %}">
{{ form_label(o_form.timeEnd) }}
{{ form_widget(o_form.timeEnd, {'attr' : {'class' : 'tm-timepatch-end'}}) }}
{{ form_errors(o_form.timeEnd) }}
</div>
<div class="col-lg-12 {% if not o_form.note.vars.valid -%}has-error{%- endif %}">
{{ form_label(o_form.note) }}
{{ form_widget(o_form.note, {'attr': {'class' : 'tm-timepatch-note', 'rows': 4 }}) }}
{{ form_errors(o_form.note) }}
</div>
</div>
<div class="form-group col-lg-3">
<label for="{{ o_form.submit.vars.id }}"> </label>
{{ form_row(o_form.submit, {'attr':{'class':'btn-default tm-action-timepatch'}}) }}
</div>
</fieldset>
{{ form_end(o_form) }}<!-- /.tm-patching-form-inline -->
UPDATE_2:
My Goal is to put the error-message from that particular consraint. Not from all other. Only errors from NotOverlapPreviousRecord
should be "moved" to {{form_errors(o_form)}}
block. All other Validators/Constraints should work as usual