IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Pré-charger une valeur dans select2 ou un attribut d'input


Sujet :

Symfony PHP

  1. #1
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2010
    Messages : 153
    Points : 107
    Points
    107
    Par défaut Pré-charger une valeur dans select2 ou un attribut d'input
    Bonjour à tous,
    J'utilise le plugin javascript select2 dans symfony pour avoir un champ permettant de choisir une (ou plusieurs) villes.
    Je me sers de l'autocomplétion de select2 pour proposer des villes.
    Ca marche mais quand je veux afficher un formulaire rempli avec des données, je ne sais pas comment donner la valeur.

    le twig :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	{{ form_row(form.address.street) }}
    	{{ form_row(form.address.city.id) }}
    La classe pour charger les données de l'adresse dans le formulaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class AddressType extends AbstractType
    {
    	public function buildForm(FormBuilderInterface $builder, array $options) {
    		$builder
    			->add('street', TextType::class, ['label' => 'address.street'])
    			->add('city', CityType::class, ['data_class' => 'MyBundle\Entity\City'])
    		;
    	}
    }
    Et celle pour la ville :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class CityType extends AbstractType
    {
     
    	public function buildForm(FormBuilderInterface $builder, array $options) {
    		$builder->add('id', ChoiceType::class, [
    			'expanded' => false,
    			'multiple' => false,
    			'label' => 'address.citycode',
    			'attr' => ['data-city' => 'true']
    			//'choices' => [],
    		]);
    	}
    }
    Et le javascript:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    $(document).ready(function () {
        $("[data-city]").each(function () {
            initAutocompleteCity(this);
        });
    });
     
    function initAutocompleteCity(selector) {
        console.log($(selector).id);
        $(selector).select2({
            ajax: {
                url: "ajax/cities",
                dataType: 'json',
                delay: 250,
                cache: true,
                processResults: function (data) {
                    return{results: data};
                }
            },
            minimumInputLength: 3,
            multiple: $(selector).attr('multiple'),
            allowClear: $(selector).attr('multiple')
                //placeholder: "Entrer un code postal"
        });
    }
    select2 a une propriété data qui permet d'initialiser avec les choix enregistrés en base, mais ma fonction est faite pour initialiser plusieurs champs dans une même page.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $('select').select2({ data: [ { id: 'value', text: 'Text to display' },    '... more data objects ...'  ] });
    Je ne sais donc pas comment faire pour que chaque champs soit initialisé avec sa (ses) ville(s) choisies précédemment.
    J'imaginais utiliser 'attr' => ['data-city' => XXX] en remplaçant pas un objet JS comme celui requi par data et de récupérer la valeur lors de l'initialisation, mais comment dire au builder de récupérer une valeur construite pour chaque objet (une méthode de mon objet City) ?

    Je peux peut-être utiliser aussi "choices" mais je crain que ce soit écrasé à la première requête ajax. Et la même question se pose : comment appeler la méthode de l'objet City qui pourrait créer l'information ?

    Peut-être aurez-vous la réponse ou une autre solution,
    Merci !!

  2. #2
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2010
    Messages : 153
    Points : 107
    Points
    107
    Par défaut
    En attendant des réponses, je teste des choses.

    Je ne peux pas utiliser 'choices' commenté dans mon exemple, ça n'accepte pas de closure.

    Je tente de ne pas passer par CityType en modifiant le twig (suppresion de '.id' après city) et modifier AdressType ainsi (à la place d'appeler CityType):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ->add('city', ChoiceType::class, [
    				'expanded' => false,
    				'multiple' => false,
    				'label' => 'address.citycode',
    				'attr' => ['data-city' => function($city) {
    						echo $city->getName();
    						return $city->getName();
    					}],
    				'choice_value' => function($city) {
    					echo $city->getId();
    					return $city->getId();
    				},
    				'choice_name' => function($city) {
    					echo $city->getName().'--';
    					return $city->getName();
    				}
    'attr' ne marche pas tel quel car on ne peut pas donner un closure comme valeur utilisée par twig (erreur "Object of class Closure could not be converted to string"). EZt on ne peut pas donner de closure genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     function($city) {echo $city->getId();return $city->getId();}
    (erreur The option "attr" with value Closure is expected to be of type "array", but is of type "Closure")

    'choice_value' me permet d'afficher l'ID sur la page, donc ça passe dedans.

    Par contre, 'choice_name' n'est pas utilisé, le nom ne s'affiche pas sur la page (même pas '--').

    Cela ne suffit pas à remplir mon champs dans la page.


  3. #3
    Membre éprouvé
    Homme Profil pro
    Développeur Web
    Inscrit en
    Novembre 2013
    Messages
    739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Novembre 2013
    Messages : 739
    Points : 1 022
    Points
    1 022
    Par défaut
    Bonjour,
    C'est juste une proposition.
    J'ai compris que tu veux utiliser Multiple select boxes detaillé ici
    Ce qui va changer avec ajax réellement ce sont les balises du genre <option value="AL">Alabama</option> .
    Alors pourquoi ne pas faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
                    success: function (data) {
                        if (data) {
                            var myitem = "";
                            $.each(data, function (index, value) {
                                myitem = index.trim();
                                var selectedItems = $("select").select2("data");
                                if (selectedItems instanceof Object)
                                {
                                    $.each(selectedItems, function (ind, val) {
     
                                        if (val['id'])
                                        {
                                            myitem = myitem + "," + val['id'];
                                        }
                                    });
                                }
     
                                $("select").val(myitem.split(',')).trigger('change');
     
                            });
                        }
                    }
    ou le data est array json contenant des objets villes etc ..
    Tu peux aussi faire vider la balise <select> avec Jquery et la remplir avec les nouvelles options juste OnSuccess

  4. #4
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2010
    Messages : 153
    Points : 107
    Points
    107
    Par défaut
    Merci pour cette proposition, depuis dans la nuit j'ai compris une partie du problème.

    J'ai pu faire l'affichage et le remplissage correct comme je cherchais de la manière suivante :

    Twig:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    		{{ form_row(form.addresscity, {'attr':{'type':"small_int",'data-city':'address.city'}}) }}
    		<script>selectedCities['address.city'] = [{{ addressCity | raw }}]</script>
    Dans le controller du formulaire, j'ajoute les données :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return $this->render('mon.html.twig', [..., 'addressCity' => $file->getAddress() != null ? CityType::citiesForJs($file->getAddress()->getCity()) : '']);
    citiesForJs() renvoie un objet JS correspondant au format de select2 avec les valeurs présentent.

    Le JS:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    function initAutocompleteCity(selector) {
        var cities = typeof selectedCities == "undefined" ? [] : selectedCities[$(selector).data('city')];
        $(selector).select2({
            data: cities,
            ajax: {
                url: "ajax/cities",
                dataType: 'json',
                delay: 250,
                cache: true,
                processResults: function (data) {
                    return{results: data};
                }
            },
            minimumInputLength: 3,
            multiple: $(selector).attr('multiple'),
            allowClear: true,
            selectOnClose: false
        });
    }
    De cette manière je charge bien les données que je veux et tout marche... jusuq'à la réception où là, comme je dit, citi.id n'avait aucune valeur de départ, donc n'importe qu'elle valeur qui arrive fait une erreur
    “Unable to reverse value for property path 'id' for Symfony2 form ChoiceType field on Select2

    J'en suis donc là, si je mets 'mapped' à false comme attribut (attr) lors de l'ajout du ChoiceType 'id' il fait la même erreur, il ne map pas sur un objet mais il veut quand même une valeur de sa liste de départ.

  5. #5
    Membre régulier
    Profil pro
    Développeur Web
    Inscrit en
    Octobre 2010
    Messages
    153
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Octobre 2010
    Messages : 153
    Points : 107
    Points
    107
    Par défaut
    Et bien je n'ai pas trouvé de solution propre qui fonctionne.
    Le problème est qu'avec un champ géré par symfony doit avoir les valeurs possibles à la création du formulaire afin de les valider au retour. Mais dans un cas d'Ajax il n'a pas les données au départ donc toute valeur est invalide !
    Il y aurait une solution intégrée avec EventSubscriberInterface avec un tuto ici http://showmethecode.es/php/symfony/...pendent-forms/ mais que je n'ai pas pu faire fonctionner dans mon cas.

    Donc solution pas propre : renseigner des données javascript, bricoler à l'arrivée sur la page et à la soumission du formulaire, et récupérer la valeur dans le "request" du contrôleur.

Discussions similaires

  1. Réponses: 2
    Dernier message: 23/12/2009, 13h33
  2. charger une valeur dans un Textinput
    Par jbtz64 dans le forum ActionScript 3
    Réponses: 2
    Dernier message: 18/01/2009, 09h50
  3. Réponses: 3
    Dernier message: 28/01/2004, 14h55
  4. Lire une valeur dans le registre
    Par John.s dans le forum C
    Réponses: 2
    Dernier message: 26/11/2003, 19h55
  5. Prendre une valeur dans la grappe XML
    Par Sandrine75 dans le forum XMLRAD
    Réponses: 7
    Dernier message: 21/05/2003, 10h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo