Archive for twig

Extending different layouts for Ajax requests in Twig, Symfony2

I just learned about the ‘app’ global variable in twig. It’s very handy for loading a special layout for ajax requests.

{% extends app.request.isXmlHttpRequest ? “::ajaxLayout.html'clear:both;'>

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"brush: php; auto-links: false;"> <?php namespace Application\BlogBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller, Symfony\Component\HttpFoundation\Response, Symfony\Component\HttpFoundation\RedirectResponse, Symfony\Component\HttpKernel\Exception\NotFoundHttpException, Sensio\Bundle\FrameworkExtraBundle\Configuration\Route, Sensio\Bundle\FrameworkExtraBundle\Configuration\Template, Application\BlogBundle\Entity\Post; /** * @Route("/post") */ class PostController extends Controller { protected $ajax = false; protected $em; protected $owner; protected $request; public function init() { $this->request = $this->get('request'); if($this->request->isXmlHttpRequest()) { $this->ajax = true; } $this->em = $this->get('doctrine.orm.entity_manager'); $this->user = $this->get('security.context')->getToken()->getUser(); $this->owner = $this->user->getOwner(); } public function getPost($id) { $post = $this->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() { $this->init(); $post = new Post(); $form = $this->get('form.factory')->create(new PostType()); $form->setData($post); if ($this->request->getMethod() == 'POST') { $form->bindRequest($this->request); if ($form->isValid()) { $post->setOwner($this->owner); $this->em->persist($post); $this->em->flush(); $this->get('session')->setFlash('notice', 'Post created!'); return $this->redirect($this->generateUrl('blog_post_list'), 301); } } return array( 'ajax' => $this->ajax, 'form' => $form->createView(), 'post' => $post, ); } }

entity/Post.html"brush: php; auto-links: false;"> <?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; } }

form/Type/PostType.html"brush: php; auto-links: false;"> <?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'); } }

Resources/views/Post/form.html"brush: php; auto-links: false;"> <div {% if ajax %} class="formDialog" {% endif %} title="New Post" style="width: 600px;"> <form method="post" action="{{ path("blog_post_new") }}" {{ form_enctype(form) }}> {{ form_widget(form) }} {{ form_rest(form) }} {% if not ajax %} <div> <input type="submit" class="button" value="Create Post"/> </div> {% endif %} </form> </div>

web/js/common.js

        // 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");
                }
            }
        });

Screenshots



Feedback appreciated!