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

ASP.NET MVC Discussion :

Comment récupérer l'objet sélectionné dans un DropDownList


Sujet :

ASP.NET MVC

  1. #1
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut Comment récupérer l'objet sélectionné dans un DropDownList
    Bonjour,

    j'ai développé un formulaire dans lequel l'utilisateur sélectionne d'abord un continent dans un DropDownList. Une fois le continent sélectionné, les pays correspondant sont chargés en base et affichés dans un second DropDownList.
    Comment puis-je récupérer l'objet bindé que l'utilisateur a sélectionné dans le DropDownList ?

    Tout d'abord, je possède une classe AtlasVM exposant une propriété pour l'identifiant du continent sélectionné, une autre pour l'identifiant du pays sélectionné et les 2 listes de continents et de pays.

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        public class AtlasVM
        {
            [Display(Description="Continent:")]
            public int? SelectedContinentId { get; set; }
            [Display(Description = "Pays:")]
            public int? SelectedCountryId { get; set; }
     
            public IEnumerable<Continent> Continents { get; set; }
            public IEnumerable<Country> Countries { get; set; }
        }

    Le code du formulaire est le suivant:

    Code asp.net : 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
    <fieldset>
                <legend>Atlas</legend>
                <% using (Html.BeginForm()) %>
                <%  { %>
                <div>
                    <label>
                        Continent</label>
                    <%= Html.DropDownListFor(m => m.SelectedContinentId, new SelectList(Model.Continents, "Id", "Name"), "[Sélectionnez un continent]")%>
                </div>
                <div>
                    <label>
                        Pays</label>
                    <%= Html.DropDownListFor(m => m.SelectedCountryId, new SelectList(Model.Countries, "Id", "Name"), "[Sélectionnez un pays]") %>
                </div>
                <input type="submit" value="Select" />
                <% } %>
            </fieldset>

    Je charge les continents dans l'action:
    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public ActionResult Index()
            {
                AtlasVM a = new AtlasVM();
                a.Continents = ContinentRepository.Default.GetContinents();
                a.Countries = new List<Country>();
                return View(a);
            }

    Enfin, j'utilise jQuery pour détecter une sélection du continent et charger les pays correspondants:

    Code javascript : 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
    <script type="text/javascript">
            $(document).ready(function () {
                $("#SelectedContinentId").change(function () {
                    var url = '<%= Url.Content("~/") %>' + "Home/SelectContinent";
                    var ddlsource = "#SelectedContinentId";
                    var ddltarget = "#SelectedCountryId";
                    $.getJSON(url, { selectedContinent: $(ddlsource).val() }, function (data) {
                        $(ddltarget).empty();
                        $(ddltarget).append("<option value=''>[Sélectionnez un pays]</option>");
                        $.each(data, function (index, optionData) {
                            $(ddltarget).append("<option value='" + optionData.Id + "'>" + optionData.Name + "</option>");
                        });
     
                    });
                });
            });
        </script>

    Donc sur sélection du continent, l'action SelectContinent du contrôleur est appelée:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public JsonResult SelectContinent(int selectedContinent)
            {
                JsonResult result = new JsonResult();
                result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
                result.Data = CountryRepository.Default.GetCountries(selectedContinent);            
                return result;
            }

    Et enfin sur validation du formulaire,

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult Index(AtlasVM c)
            {
                Atlas a = new Atlas();
                a.SelectedContinent = c.Continents.FirstOrDefault(cont => cont.Id == c.SelectedContinentId);
                a.SelectedCountry = c.Countries.FirstOrDefault(count => count.Id == c.SelectedCountryId);
                AtlasRepository.Default.Save(a);
     
                return View("Valid");
            }

    Comment puis-je procéder svp ?

    Merci d'avance,
    Etienne

  2. #2
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Par défaut
    Salut,

    Je viens de regarder le code que tu as posté, et je ne vois pas de problèmes particulier, ni ne sais quel est le problème rencontré. Du coup je ne sais pas trop ce qui te bloque ni donc comment t'aider.

  3. #3
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Bonjour,

    merci pour la réponse.
    Je viens de regarder le code que tu as posté, et je ne vois pas de problèmes particulier, ni ne sais quel est le problème rencontré. Du coup je ne sais pas trop ce qui te bloque ni donc comment t'aider.

    Oui effectivement, je viens de m'apercevoir que j'ai fait une erreur dans mon message précédent. J'ai omis une information essentielle:
    En réalité, le code suivant ne fonctionne pas

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    AcceptVerbs(HttpVerbs.Post)]
            public ActionResult Index(AtlasVM c)
            {
                Atlas a = new Atlas();
                a.SelectedContinent = c.Continents.FirstOrDefault(cont => cont.Id == c.SelectedContinentId);
                a.SelectedCountry = c.Countries.FirstOrDefault(count => count.Id == c.SelectedCountryId);
                AtlasRepository.Default.Save(a);
     
                return View("Valid");
            }

    car c.Continents et c.Countries sont nulls. Ce qui est logique quelque part.
    En réalité, j'aurais voulu récupérer directement le continent et le pays sélectionnés et pas juste l'identifiant.
    Est-ce que tu vois ce que je veux dire ?
    Est-ce que c'est possible ?

    Merci d'avance,
    Etienne

  4. #4
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Par défaut
    Ok, merci c'est plus clair.

    En fait tu voudrais stocker à la fois les continents et l'id du continent sélectionné, pour pouvoir faire ton where plus simplement. Techniquement c'est possible de stocker une liste à grand coups d'hiddens, mais c'est long, source d'erreurs et inutile.

    Deux solutions s'offrent à toi:
    • Tu utilises la méthode UpdateModel pour faire une fusion de tes données postés et d'un objet.
      Edit: la version update model ne marchera pas bien: il arrivera à faire l'update model, mais la liste des pays sera vide...
    • Ou tu fais tout le traitement à la main, en réinterrogeant ton repository.



    Voila, donc t'as pas le choix, tu va devoir réinterroger ton repository pour re-récupérer le continent puis le pays.

    Ensuite en termes d'optimisations il doit être possible de mettre en cache la liste des pays et continents, mais c'est un autre sujet.

  5. #5
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Bonsoir,

    merci pour la réponse.
    Est-ce que je ne pourrais pas par exemple, lorsque l'utilisateur a sélectionné le continent dans le DropDownList, exécuter une fonction JavaScript qui recherche l'objet correspondant dans la liste Model.Continents et l'affecte à la propriété SelectedContinent du Model ?

    Merci d'avance,
    Etienne

  6. #6
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Je vais répondre tout seul à ma question.

    Est-ce que je ne pourrais pas par exemple, lorsque l'utilisateur a sélectionné le continent dans le DropDownList, exécuter une fonction JavaScript qui recherche l'objet correspondant dans la liste Model.Continents et l'affecte à la propriété SelectedContinent du Model ?
    Et bien non ce n'est pas possible car le JavaScript c'est côté client et Model.Continents est côté serveur. Cette collection n'a pas d'existence côté client.

    N'est-ce pas ?

    Etienne

  7. #7
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Par défaut
    Re,

    Tu as très bien répondu à ta question, c'est tout à fait ça. Pour réaliser ce comportement, il faut soit que tu stockes toutes les infos des continent dans ta page, soit que tu le fasses par un appel ajax au serveur.

    Du coup, tu peux utiliser ton action ajax SelectContinent pour récupérer ces informations et l'affecter à plusieurs hidden représentant SelectedContinent .

    Pour cela, il faut que tu créé autant d'hidden, que tu as de propriétés sur tes continents ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <%= Html.HiddenFor(model => model.SelectContinent.Id) %>

  8. #8
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Bonjour,

    merci pour la réponse.
    Comme tu l'as dit précédemment, ce serait une solution un peu lourde.
    Je vais donc faire comme tu l'as dit, je vais aller rechercher l'objet dans la base.

    Cordialement,
    Etienne

  9. #9
    Membre éclairé
    Inscrit en
    Juillet 2004
    Messages
    306
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 306
    Par défaut
    Bonjour,

    je viens d'avoir une autre idée.
    Serait-il possible de stocker la liste d'objets en mémoire côté serveur, dans un cache par exemple, dans une variable de session ou autre ?

    Ainsi lorsque l'utilisateur valide le formulaire, je récupère l'objet sélectionné en interrogeant la collection à partir de l'id.

    Le stockage de cette collection devra être propre à chaque utilisateur.
    Pour information, il y aura une 50aine d'utilisateurs, il est vrai que ça pourrait potentiellement représenter une forte consommation mémoire.

    Qu'en dites-vous ?

    Merci d'avance
    Etienne

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 29/04/2008, 15h33
  2. Réponses: 3
    Dernier message: 25/04/2008, 11h25
  3. Comment récupérer le texte sélectionné dans une liste déroulante ?
    Par Je-cherche-pfe dans le forum Windows Forms
    Réponses: 3
    Dernier message: 02/09/2007, 20h35
  4. Réponses: 1
    Dernier message: 18/05/2006, 11h37
  5. Réponses: 3
    Dernier message: 13/12/2005, 00h21

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