Symfony 4 handling null DateType form field
You should allow put null in method setDateOfBirth. The correct version:
public function setDateOfBirth(?\DateTimeInterface $DateOfBirth): self
{
$this->DateOfBirth = $DateOfBirth;
return $this;
}
Because entity is populated values from request by setters before validating
Use the empty_data
option to do this.
$builder
->add('someDate', \Symfony\Component\Form\Extension\Core\Type\DateType::class, [
'widget' => 'single_text',
'required' => false,
'empty_data' => '',
])
;
The default value of by_reference
option in DateType, DateTimeType and TimeType is false
.
So in here $this->propertyAccessor->setValue($data, $propertyPath, $propertyValue);
is called and here {An instance of PatientSearch}->setDateOfBirth(null)
is called.
But argument for setDateOfBirth(\DateTimeInterface $DateOfBirth)
is not nullable. So you get that error.
You can prevent the error with making argument nullable like this:
public function setDateOfBirth(?\DateTimeInterface $DateOfBirth): self
{
$this->DateOfBirth = $DateOfBirth;
return $this;
}
or turning by_reference
true
like this:
->add('DateOfBirth', DateType::class, array(
'required' => false,
'widget' => 'single_text',
'by_reference' => true,
))
I wound up just using a TextType
to do this as it was easier and there didn't seem to be a solution with using a DateType
. In fact it looks like this is a issue being reviewed on the Symfony github issues (ticket here) as the DateTimeType
/DateType
doesn't seem to work properly with the empty_data
attribute.
The trick here is when you get the field it is a date
type, but when you set it the type is a string
which attempts to convert to datetime
and if it fails then the field is just not set. The field itself is still a date
data type.
Type file
->add('DateOfBirth', TextType::class, array(
'required' => false,
'empty_data' => null,
'attr' => array(
'placeholder' => 'mm/dd/yyyy'
)))
Twig file
{{ form_widget(search_form.DateOfBirth) }}
Entity file
/**
* @ORM\Column(type="date", nullable=true)
*/
private $DateOfBirth;
...
public function getDateOfBirth(): ?\DateTimeInterface
{
return $this->DateOfBirth;
}
public function setDateOfBirth(string $DateOfBirth): self
{
try {
$this->DateOfBirth = new \DateTime($DateOfBirth);
}
catch(\Exception $e) {
//Do Nothing
}
return $this;
}