Navigation

Related Articles

Back to Latest Articles

Symfony & jQuery DatePicker


Samuel Breton
Symfony & jQuery DatePicker

Je vais vous montrer dans cet article comment mettre en place rapidement un datePicker jQuery dans un formulaire Symfony 1.2

Pré-requis

Fichiers externes

  • Télécharger jQuery UI
    (jquery-1.3.2.min.js, jquery-ui-1.7.1.custom.min.js)

    Vous pouvez télécharger une version « customizée » de jQuery UI ici :
    Télécharger JQuery UI

  • Version française
    (uidatepicker-fr.js)

    Vous trouverez le patch français de ce plugin ici :

    Datepicker jQuery en français

  • Intégration dans Symfony
    1. JS
      Copiez les fichiers :
      [jquery UI]/js/jquery-1.3.2.min.js
      [jquery UI]/js/jquery-ui-1.7.1.custom.min.js
      uidatepicker-fr.js
      directement dans [votre_projet]/web/js
    2. CSS
      • Copiez le fichier :
        [jquery UI]/css/jquery-ui-1.7.1.custom.css dans :
        [votre_projet]/web/css.
      • !! Attention !! :
        J’ai dû remplacer toutes les occurrences de :
        url(images/ par :
        url(../images/
    3. Images
      N’oubliez pas de copier le contenu de :
      [jquery UI]/css/smoothness/images dans :
      [votre_projet]/web/images

View.yml

N’oubliez pas de faire référence aux fichiers externes dans le view :

default:
  http_metas:
    content-type: text/html
 
  metas:
    #title:        symfony project
    #description:  symfony project
    #keywords:     symfony, project
    #language:     en
    #robots:       index, follow
 
  stylesheets:    [main.css, jquery-ui-1.7.1.custom.css]
 
  javascripts:    [jquery-1.3.2.min.js, uidatepicker-fr.js, jquery-ui-1.7.1.custom.min.js]
 
  has_layout:     on
  layout:         layout

sfWidgetFormJQueryI18nDate.class.php

J’ai modifié la classe sfWidgetFormJQueryDate pour qu’elle soit compatible avec un format de date français.
De plus, on peut facilement configurer les options du widget jQuery.

  • Code source :
    Fichier : sfWidgetFormJQueryI18nDate.class.php
    Chemin : /plugins/sfFormExtraPlugin/lib/widget/

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    
    <?php
    /*
     * This file is part of the symfony package.
     * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
     * 
     * For the full copyright and license information, please view the LICENSE
     * file that was distributed with this source code.
     */
     
    /**
     * sfWidgetFormJQueryDate represents a date widget rendered by JQuery UI.
     *
     * This widget needs JQuery and JQuery UI to work.
     *
     * @package    symfony
     * @subpackage widget
     * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
     * @version    SVN: $Id: sfWidgetFormJQueryDate.class.php 12875 2008-11-10 12:22:33Z fabien $
     */
    class sfWidgetFormJQueryI18nDate extends sfWidgetFormI18nDate
    {
      /**
       * Configures the current widget.
       *
       * Available options:
       *
       *  * image:   The image path to represent the widget (false by default)
       *  * config:  A JavaScript array that configures the JQuery date widget
       *  * culture: The user culture
       *
       * @param array $options     An array of options
       * @param array $attributes  An array of default HTML attributes
       *
       * @see sfWidgetForm
       */	
     
      protected function configure($options = array(), $attributes = array())
      {
        $this->addOption('image', false);
        $this->addOption('config', $options["config"]);
        $this->addOption('culture', $options["culture"]);
        $this->addOption('years', $options["years"]);
     
        parent::configure($options, $attributes);
     
        if ('en' == $this->getOption('culture'))
        {
          $this->setOption('culture', 'en');
        }
      }
     
      /**
       * @param  string $name        The element name
       * @param  string $value       The date displayed in this widget
       * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
       * @param  array  $errors      An array of errors for the field
       *
       * @return string An HTML tag string
       *
       * @see sfWidgetForm
       */
      public function render($name, $value = null, $attributes = array(), $errors = array())
      {
        $prefix = $this->generateId($name);
     
        $image = '';
        if (false !== $this->getOption('image'))
        {
          $image = sprintf(', buttonImage: %s, buttonImageOnly: true', $this->getOption('image'));
        }
        return parent::render($name, $value, $attributes, $errors).
               $this->renderTag('input', array('type' => 'hidden', 'size' => 10, 'id' => $id = $this->generateId($name).'_jquery_control', 'disabled' => 'disabled')).
               sprintf(<<<EOF
    <script type="text/javascript">
     
      function %s_read_linked()
      {
        \$("#%s").val(\$("#%s").val() + "/" + \$("#%s").val() + "/" + \$("#%s").val());
     
        return {};
      }
     
      function %s_update_linked(date)
      {
        \$("#%s").val(date.substring(0, 2));
        \$("#%s").val(parseInt(date.substring(3, 5), 10));
        \$("#%s").val(date.substring(6, 10));
      }
     
      \$("#%s").datepicker(\$.extend({}, {
        minDate:    new Date(%s, 1 - 1, 1),
        maxDate:    new Date(%s, 12 - 1, 31),
        onSelect:   %s_update_linked,
        beforeShow: %s_read_linked,    
        %s    
        showOn:     "both"
        %s
      }, \$.datepicker.regional["%s"]));
     
    </script>
    EOF
          ,
          $prefix, $id,
          $this->generateId($name.'[day]'), $this->generateId($name.'[month]'), $this->generateId($name.'[year]'),
          $prefix,
          $this->generateId($name.'[day]'), $this->generateId($name.'[month]'), $this->generateId($name.'[year]'),
          $id,
          min($this->getOption('years')), max($this->getOption('years')),
          $prefix, $prefix, $this->getOption('config'), $image, $this->getOption('culture')
        );
      }
    }
  • Explication des modifications :
    1. Ligne 20 :
      Notre widget dérive désormais de sfWidgetFormI18nDate

      20
      
      class sfWidgetFormJQueryDate extends sfWidgetFormI18nDate
    2. Lignes 40, 41 et 42:
      On ajoute les options « config », « culture » et « years » avec le paramètre « options » de la fonction « configure » :

      40
      41
      42
      
        $this->addOption('config', $options["config"]);
        $this->addOption('culture', $options["culture"]);
        $this->addOption('years', $options["years"]);
    3. Lignes 85 et 86
      • Il faut inverser l’ordre du jour et du mois pour être compatible avec un format français, ce qui revient dans un sprintf, à changer l’ordre des lignes dans le code.
      • Il faut faire un parseInt sur le mois pour transformer « 01 » en « 1 », parseInt est la fonction javascript permettant de caster une chaîne de caractères en Integer :
        Premier paramètre : la chaîne à caster (ici : date.substring(3, 5) )
        Deuxième paramètre : Le système numérique à utiliser (ici décimal : 10)
      85
      86
      
          \$("#%s").val(date.substring(0, 2));
          \$("#%s").val(parseInt(date.substring(3, 5), 10));
    4. Lignes 95 et 109
      • On passe les options directement dans le premier argument.
        Le %s de la ligne 95 correspond au $this->getOption(‘config’) de la ligne 109
        Le %s de la ligne 98 correspond au $this->getOption(‘culture’) de la ligne 109
      • Ligne 109 : passage des options et da la culture au widget.
      108
      
      $prefix, $prefix, $this->getOption('config'), $image, $this->getOption('culture')

Exemple d’utilisation

  • Schéma
    person:
      columns:
        [...]
        birthday:
          type: timestamp
        [...]
  • Formulaire (Instanciation du widget)
      [...]
      public function configure()
      {
        for($i = 1900; $i<2010; $i++)
        {
          $years[$i] = $i;
        }
        $this->widgetSchema['birthday'] = new sfWidgetFormJQueryI18nDate(
          array('config' => 'yearRange: \'1900:2009\', 
                               changeYear: true, 
                               changeMonth: true,',
                'culture' => 'fr',
                'years'=> array_combine($years, $years))
          );   
      }
      [...]
  • Aperçu
    jquery datepicker fr

Sources

Show Comments (17)

Comments

  • sessime

    Salut,
    Merci pour ce billet qui m’aide à implementer ce calendrier.
    Mais le plugin que j’ai telechargé sur le site de symfony je n’ai pas ce fichier sfWidgetFormJQueryI18nDate.class.php à l’endroit indiqué /plugins/sfFormExtraPlugin/lib/widget/ ,j’ai plutot celui sfWidgetFormJQueryDate.class.php ou vous aviez renommé ce fichier pour avoir l’autre.
    Priere me donner des pistes.
    Merci d’avance.

    • Article Author
  • Lionel (ex-lexik)

    Salut,
    Oui j’ai renommé le fichier, et je l’ai modifié pour qu’il gère l’i18n. La classe hérite de ‘sfWidgetFormI18nDate’ et plus de ‘sfWidgetFormDate’.
    Merci pour l’intérêt que vous portez au blog de Lexik =)

    • Article Author
  • Mac Curty

    Bonjour,

    merci pour ce petit tuto, tout marche bien à l’exception d’une petite chose :

    Quand je choisis une date avec le calendrier, il n’y a que les 3 derniers mois qui fonctionnent. Par exemple si je sélectionne une date en mars, le jour et l’année s’affichent correctement dans la partie gauche mais le moi reste vide …

    Si vous avez une idée je suis preneur.

    Bye

    • Article Author
  • TomTom

    Merci pour ce tutoriel.
    C\’est à deux doigts de fonctionner pour moi, mis à part le fait que les mois et les jours sont inversés ! Je m\’explique :
    Les champs du formulaire contiennent \"12 mars 2008\", et dans le widget jQuery, la date par défaut est 3 décembre 2008\". 12/03 correspond à 03/12 et inversement.

    Sur votre exemple, on est au 08/08/1979, forcément ça fonctionne dans les deux sens !

    Vous n\’avez pas ce souci pour les autres dates ?

    • Article Author
  • Empouioui

    Encore un merci pour ce tutoriel,
    Je débute avec Symfony (1.2) et je me retrouve à travailler sur un projet conséquent.
    Votre blog, en général, m\’ai d\’un grand secoure pour comprendre de nombreuses subtilités de ce framework !

    Merci encore !

    PS: Pas de souci pour aucunes dates en ce qui me concerne …

    • Article Author
  • Nicolas

    Ca n’a pas l’air de fonctionner avec symfony 1.4.1 :/

    • Article Author
  • Mohammed CHERIFI

    @Nicolas dans symfony 1.4.1 on a pas à inverser l\’ordre du jour et du moins, le plugin supporte désormais un paramètre "date_widget" ou tu peux renseigner le format de la date que tu souhaites

    • Article Author
  • loulouraph

    Hello,

    Pour rendre un peu plus français le widget, je rajoute un config en plus : firstDay: 1, ce qui fait commencer la semaine au lundi.

    • Article Author
  • Laurent

    Merci pour ce tuto.

    J’aimerai n’avoir qu’un champ date au lieu d’avoir 3 champs : jour, mois et année. Que dois-je changer ?

    Merci d’avance,

    Symfony 1.4
    Netbeans 6.8
    php 5.3

    • Article Author
  • Benoit

    Merci pour ce tuto qui m’a permis d’implémenter le datepicker, non sans mal ceci dit ! mais ça fonctionne.

    Par contre, comment fait-on pour inverser l’ordre des select jour et mois ? J’ai toujours le select mois avant le select jour…

    Bon courage pour la suite, continuez comme ça !

    • Article Author
  • hmz

    merci pour ce tuto mais j\’ai un petit probleme

    mon probleme c\’est que j\’ai eu le calendreir et tou vas bien mais lorsque je selectionne une date j\’aurais toujours un ou deux champs (jour et mois) manquant
    j\’ai toujour des valeur vide dans ce deux liste

    je ne sais pas d\’où provient cette erreur

    • Article Author
  • hmz

    merci pour ce tuto mais j\\\’ai un petit probleme

    mon probleme c\\\’est que j\\\’ai eu le calendreir et tou vas bien mais lorsque je selectionne une date j\\\’aurais toujours un ou deux champs (jour et mois) manquant
    j\\\’ai toujour des valeur vide dans ce deux liste

    je ne sais pas d\\\’où provient cette erreur

    • Article Author
  • horloge

    Quelle version du plugin as-tu car dans la version 1.3 de sfFormExtraPlugin il y a un problème avec la fonction parseInt()

    • Article Author
  • TiM

    Merci beaucoup !

    En partant de ce tuto, j’ai ai fait un nouveau, un peu plus récent, un peu plus simple, si ça peu aider du monde :

    http://tim.lepton.fr/blog/2010/09/14/utiliser-jquery-datepicker-dans-un-admin-symfony-en-francais/

    • Article Author
  • Sebastien

    Bonjour,

    Ce tuto marche-t-il avec symfony 1.0.22?

    merci

    • Article Author
  • kévin

    Bonjour,

    J’essaie d’implémenter sur le même principe un widget qui gère aussi l’heure, comme ici => http://trentrichardson.com/examples/timepicker

    Quelqu’un est-il déjà passé par là? J’ai commencé par étendre la classe à sfWidgetFormI18nDateTime et vu que c’est jquery qui gère, je ne vois pas trop quelles options passer à la méthode getTimeWidget()..

    Si quelqu’un a une idée je suis preneur 🙂

    • Article Author
  • j0k

    @kevin
    Je cherchais justement et j’ai trouvé:
    http://garakkio.altervista.org/datepicker/

    • Article Author

Recevez nos articles