Adding JQuery UI Datepicker and timepicker to Symfony2 forms

I am a big fan of being able to customise form layout without editing each field individually.

Here I will show how to add a class attribute to a date and time field so that it can utilise the JQuery UI datepicker and timepicker. I also make use of the JQuery modal dialog for the form itself.

controller/PostController.html?php namespace Application\BlogBundle\Controller; use Symfony\Component\DependencyInjection\ContainerAware, Symfony\Component\HttpFoundation\RedirectResponse, Sensio\Bundle\FrameworkExtraBundle\Configuration\Method, Sensio\Bundle\FrameworkExtraBundle\Configuration\Route, Sensio\Bundle\FrameworkExtraBundle\Configuration\Template, Symfony\Component\HttpFoundation\Response, Symfony\Component\HttpFoundation\RedirectResponse, Symfony\Component\HttpKernel\Exception\NotFoundHttpException, Application\BlogBundle\Entity\Post; /** * @Route("/post") */ class PostController extends ContainerAware { protected $ajax = false; public function getPost($id) { $em = $this->container->get(‘doctrine.orm.entity_manager’);
$post = $em->getRepository(‘Application\BlogBundle\Entity\Post’)->find($id);
if (!$post) {
throw new NotFoundHttpException(“Post not found”);
} else {
return $post;
}
}

/**
* @Route(“/new”, name=”blog_post_new”)
* @Template()
*/
public function newAction()
{
$request = $this->container->get(‘request’);
$em = $this->container->get(‘doctrine.orm.entity_manager’);

$post = new Post();

$form = $this->container->get(‘form.factory’)->create(new PostType());

$form->setData($post);

if ($request->getMethod() == ‘POST’) {
$form->bindRequest($request);

if ($form->isValid()) {
$em->persist($post);
$em->flush();

$this->get(‘session’)->setFlash(‘notice’, ‘Post created!’);

return new RedirectResponse( $this->container->get(‘router’)->generate(‘blog_post_list’), 301);

}
}

return array(
‘ajax’ => $this->ajax,
‘form’ => $form->createView(),
‘post’ => $post,
);
}
}
[/php]

entity/Post.html?php namespace Application\BlogBundle\Entity; use Doctrine\Common\Collections\ArrayCollection, Doctrine\ORM\Mapping as ORM, Symfony\Component\Validator\Constraints as Assert; /** * @orm\Entity(repositoryClass="Application\BlogBundle\Entity\Repository\PostRepository") */ class Post { /** * @orm\id * @orm\Column(type="integer") * @orm\GeneratedValue(strategy="AUTO") */ private $id; /** @orm\ManyToOne(targetEntity="Application\UserBundle\Entity\User") */ private $owner; /** @orm\Column(type="string", length="10", nullable="true") */ private $date; /** @orm\Column(type="string", length="10", nullable="true") */ private $time; /** @orm\Column(type="string", length="150") */ private $post; /** @orm\Column(type="datetime", nullable="true") * @var \DateTime */ private $createdAt; /** @orm\Column(type="datetime", nullable="true") * @var \DateTime */ private $updatedAt; /** @orm\PrePersist */ public function PrePersist() { $this->createdAt = new \DateTime(‘now’);
}

/** @orm\PreUpdate */
public function PreUpdate()
{
$this->updatedAt = new \DateTime(‘now’);
}

/**
* Get id
*
* @return integer $id
*/
public function getId()
{
return $this->id;
}

/**
* Set date
*
* @param string $date
*/
public function setDate($date)
{
$this->date = $date;
}

/**
* Get date
*
* @return string $date
*/
public function getDate()
{
return $this->date;
}

/**
* Set time
*
* @param string $time
*/
public function setTime($time)
{
$this->time = $time;
}

/**
* Get time
*
* @return string $time
*/
public function getTime()
{
return $this->time;
}

/**
* Set post
*
* @param string $post
*/
public function setPost($post)
{
$this->post = $post;
}

/**
* Get post
*
* @return string $post
*/
public function getPost()
{
return $this->post;
}

/**
* Set owner
*
* @param Application\UserBundle\Entity\User $owner
*/
public function setOwner(\Application\UserBundle\Entity\User $owner)
{
$this->owner = $owner;
}

/**
* Get owner
*
* @return Application\UserBundle\Entity\User $owner
*/
public function getOwner()
{
return $this->owner;
}
}
[/php]

form/Type/PostType.html?php namespace Application\BlogBundle\Form\Type; use Symfony\Component\Form\AbstractType, Symfony\Component\Form\FormBuilder ; class PostType extends AbstractType { public function getName() { return 'PostType'; } public function buildForm(FormBuilder $builder, array $options) { $builder ->add(‘date’, ‘date’, array(
‘attr’ => array(‘class’ => ‘date’),
‘widget’ => ‘single_text’,
‘input’ => ‘string’,
‘format’ => ‘dd/MM/yy’, //\IntlDateFormatter::FULL
))
->add(‘time’, ‘time’, array(
‘attr’ => array(‘class’ => ‘time’),
‘widget’ => ‘single_text’,
‘input’ => ‘string’
))
->add(‘post’, ‘textarea’);
}
}
[/php]

Resources/views/Post/form.html"formDialog" {% endif %} title="New Post" style="width: 600px;">

{{ form_widget(form) }}
{{ form_rest(form) }}
{% if not ajax %}

{% endif %}

[/php]

web/js/common.js
[php]
// see https://jqueryui.com/demos/datepicker/” for more info
$(“form input.date”).datepicker({
dateFormat: ‘yy-mm-dd’
});

//see https://trentrichardson.com/examples/timepicker for more info
$(“form input.time”).timepicker({
stepMinute: 15,
ampm: true,
hourMin: 6,
hourMax: 20
});

$(“.formDialog”).dialog({
autoOpen: true,
minHeight: ‘325’,
minWidth: $(“.formDialog”).width(),
position: ‘center’,
modal: true,
show: ‘slide’,
hide: ‘slide’,
close: function() { $(this).dialog(“destroy”).remove();},
buttons: {
‘Save': function() {
disableSaveButton( $(this) );
showSpinner();
$(“.formDialog form”).submit();
},
‘Cancel': function() {
$(this).dialog(“close”);
}
}
});
[/php]
Screenshots



Feedback appreciated!