Symfony2: exemple d’un Champ de Type Slider

Je vous propose de découvrir une solution pour doter un formulaire Symfony 2 d’un champ de type slider. La grande flexibilité du constructeur de formulaires du framework, nous permet en quelques lignes de code d’utiliser le très bon plugin Ion.RangeSlider.

Etant très pressé je vais simplement poser le code. L’utilisation du plugin n’a pas été conservé dans le projet sur lequel je travaillais, donc de nombreuses améliorations sont possibles.

Vous trouverez à l’adresse citée au-dessus le lien pour télécharger le plugin, qui fonctionne avec JQuery. Placez ces fichiers dans le dossier Site\MonBundle\Ressources\Public\js\. Placez dans Site\MonBundle\Ressources\Public\css\ le css du plugin.

Le template

{#Site\MonBundle\Ressources\views/Form/fields.html.twig#}

{% block range_widget %}
<noscript>Vous devrez entrer une température entre {{ min }} et {{ max }}.</noscript>
    {% spaceless %}
        <div id="slider{{ form.vars.id }}">
        {{ form_widget( form, {'type' : 'text'} ) }}
        </div>
        {# This script allows you use range with unsupported browsers #}
    {% endspaceless %}
    {# https://github.com/IonDen/ion.rangeSlider #}
    <script>

        $("#{{ form.vars.id }}")
                .ionRangeSlider({
                        min:{{ min }},
                        max:{{ max }},
                        from: 19,
                        postfix: '{{ postfix }}',
                        {% if values == null %}
                            step: {{ step }},               
                        {% endif %}
                        {% if values != null %}
                            values: [
                            {% for value in values %}
                                {{ value }}
                                {% if not loop.last %},{% endif %}
                            {% endfor %}
                            ]
                        {% endif %}
                });

    </script>
{% endblock %}

Le champ personnalisé Pour me simplifier la déclaration de services, j’utilise le bundle https://packagist.org/packages/jms/di-extra-bundle.

<?php
// namespace Site\MonBundle\Form\Custom;

use Symfony\Component\Form\AbstractType;
use JMS\DiExtraBundle\Annotation\Service;
use JMS\DiExtraBundle\Annotation\Tag;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;

/**
 *
 * @Service("site_monbundle.form.type.range")
 * @Tag("form.type", attributes = {"alias" = "range"})
 */
class RangeType extends AbstractType {

    private $min, $max, $default, $step, $values, $postfix;

    /**
     * Get parent
     *
     * @return string
     */
    public function getParent() {
        return 'text';
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName() {
        return 'range';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'min' => $this->min,
            'max' => $this->max,
            'default' => $this->default,
            'step' => $this->step,
            'values' => $this->values,
            'postfix' => $this->postfix
        ));
    }

    public function buildView(FormView $view, FormInterface $form, array $options) {
        $view->vars['min'] = $options['min'];
        $view->vars['max'] = $options['max'];
        $view->vars['default'] = $options['default'];
        $view->vars['step'] = $options['step'];
        $view->vars['values'] = $options['values'];
        $view->vars['postfix'] = $options['postfix'];
    }

}

l’appel à ce champ personnalisé dans un builder de form

 ->add(
          $builder->create('temperature', 'range', array(
          'min' => 0, 'max' => 40, 'default' => 19,
          'step' => 0.5, 'values' => "", 'postfix' => '°',
          'invalid_message' => "Ce n'est pas un nombre correct.")
          )
          ->addModelTransformer($transformerfloat)
          )

Le ModelTransformer permet de convertir un nombre à virgule en nombre à point afin de s’assurer d’avoir un float bien compris par Symfony 2.

<?php 
// namespace Site\MonBundle\Form\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;

class FloatFrenchTransformer implements DataTransformerInterface{

    public function transform($number)
    {
        if (null === $number) {
            return null;
        }

        return $number;
    }
    
    public function reverseTransform($number)
    {
        if (!$number) {
            return null;
        }
        
        $number = str_replace(",", ".", $number);
        
        return $number;
    }
}

le champ dans l’entité (avec contrainte de validation utilisation les Assert)

// Site\MonBundle\Entity\

// ...

/**
     * @var float
     *
     * @ORM\Column(name="temperature", type="float")
     * @Assert\Type(type="numeric", message="Vous devez entrer un nombre valide.")
     * @Assert\NotBlank()
     * @Assert\Range(
     *      min = 0,
     *      max = 40,
     *      minMessage = "La température entrée doit être comprise entre 0 et 40.",
     *      maxMessage = "La température entrée doit être comprise entre 0 et 40.",
     *      invalidMessage = "Erreur!")
     */
    private $temperature;

// ...
Publié dans PHP

quand j’aurai le temps

  • les filtres wordpress
  • plugin wordpress et enregistrement de données
  • les wordpress custom post type
  • la bdd d'un blog wordpress
  • la balise more de wp
  • personnaliser une galerie wp
  • gérer les longueurs des extraits de wp
  • les animations css3
  • le memento symphony2
  • le squelette d'une page html5
  • liste sur plusieurs colonnes
  • le responsive design
  • exemple d'un jeu basique en html5
  • la réplication des bases de données
  • mettre en place une architecture en silo avec wp
  • parser un fichier xml (donc un rss) avec php5
  • mettre en place lightbox sans plugin
  • améliorer les performances de son wp
  • ajouter un bouton à l'éditeur de texte de wp
  • ...