web-dev-qa-db-fra.com

Remplir DropDownList en utilisant AJAX MVC 4

J'ai une vue en place qui contient 2 aides de @ DropDownListFor:

    @using (Html.BeginForm("CreateOneWayTrip", "Trips"))
    {
        @Html.ValidationSummary(false);
        <fieldset>
            <legend>Enter Your Trip Details</legend>

            <label>Start Point</label>
            @Html.DropDownListFor(m => m.StartPointProvince, (SelectList)ViewBag.Provinces, new { @Id = "province_dll", @class = "form-control" })
            @Html.DropDownListFor(m => m.StartPointCity, (SelectList)ViewBag.Cities, new { @Id = "city_dll", @class = "form-control" })

            <p style="float: none; text-align: center;">
                <button type="submit" value="Create" class="btn btn-info btn-circle btn-lg">
                    <i class="fa fa-check"></i>
                </button>

                <button type="submit" value="Create" class="btn btn-warning btn-circle btn-lg">
                    <i class="fa fa-times"></i>
                </button>
            </p>
        </fieldset>
    }

Voici le modèle temporaire que j'utilise pour capturer des données:

 public class CaptureCreateTrip
 {
    [Required]
    [Display(Name = "Trip ID")]
    public string TripID { get; set; }

    [Required]
    public string StartPointProvince { get; set; }

    [Required]
    public string StartPointCity { get; set; }
}

L'un des DropsDownList est rempli lors de la création de la page et le second sera renseigné en fonction de l'option choisie par l'utilisateur dans la première liste DropDownList. Pour y parvenir, j'utilise ajax. Le javascript que j'utilise ressemble à ceci:

$("#province_dll").change(function () {
        $.ajax({
            url: 'getCities/Trips',
            type: 'post',
            data: {
                provinceId: $("#province_dll").val()
            }
        }).done(function (response) {
            $("cities_dll").html(response);
        });
    });

Voici le contrôleur que AJAX appelle:

  [HttpPost]
  public ActionResult getCicites(int provinceId)
  {
      var lstCities = new SelectList(new[] { "City1", "City2", "City3" });

      return Content(String.Join("", lstCities));
  }

Jusque-là, tout fonctionne - Lorsque je choisis une valeur dans ma province DropDown, l'événement javascript est déclenché et que l'action du contrôleur renvoie les valeurs de la liste de sélection à la ville DropDown, le problème est toutefois que les données (du format l'action retourne est incorrecte. J'ai testé cela en créant un élément de paragraphe et en mettant à jour son texte avec la valeur de retour de l'appel ajax, à savoir: "System.Web.Mvc.SelectListItemSystem.Web.Mvc.SelectListItemSystem.Web.Mvc.Select‌ ListItem"

* Remarque: je suis nouveau sur ajax et en train d'apprendre Jquery et AJAX.

14
Marnus Steyn

La raison pour laquelle vous obtenez une collection de chaînes "System.Web.Mvc.SelectListItemSystem" est que var lstCities = new SelectList(new[] { "City1", "City2", "City3" }); renvoie IEnumerable<SelectListItem> et String.Join("", lstCities) appelle la méthode .ToString() de chaque élément SelectListItem de la collection qui renvoie "System.Web.Mvc.SelectListItemSystem" (et non la valeur de la propriété Text de SelectListItem).

Le meilleur moyen de renseigner la deuxième liste déroulante consiste à renvoyer un JSON contenant la collection de villes et à mettre à jour le DOM dans le rappel ajax success. Il n'y a aucune raison de créer une SelectList - c'est simplement une surcharge inutile et vous renvoyez au moins trois fois plus de données que nécessaire (le client n'a pas de concept de classe C # SelectListItem.

public JsonResult FetchCities(int provinceId) // its a GET, not a POST
{
    // In reality you will do a database query based on the value of provinceId, but based on the code you have shown
    var cities = new List<string>() { "City1", "City2", "City3" });
    return Json(cities, JsonRequestBehavior.AllowGet);
}

Puis dans le script (vous ne savez pas pourquoi vous avez modifié la valeur par défaut id de id="StartPointProvince" à id="province_dll", mais)

var url = '@Url.Action("FetchCities", "Trips")'; // Don't hard code your url's!
var cities = $('#city_dll'); // cache it
$("#province_dll").change(function () {
    var id = $(this).val(); // Use $(this) so you don't traverse the DOM again
    $.getJSON(url, { provinceId: id }, function(response) {
        cities.empty(); // remove any existing options
        $.each(response, function(index, item) {
            cities.append($('<option></option>').text(item));
        });
    });
});

Modifier

Suite aux commentaires de OP, si la base de données contenait un nom de table Cities avec les champs ID et Name, la méthode du contrôleur ressemblerait à ceci:

public JsonResult FetchCities(int provinceId) // its a GET, not a POST
{
    var cities = db.Cities.Select(c => new
    {
      ID = c.ID,
      Text = c.Text
    }
    return Json(cities, JsonRequestBehavior.AllowGet);
}

et le script pour créer les options serait

$.each(response, function(index, item) { // item is now an object containing properties ID and Text
    cities.append($('<option></option>').text(item.Text).val(item.ID));
});
29
user3559349

Pouvez-vous essayer ce qui suit?

C’est un message que j’ai répondu il ya quelques jours . Police: DropDownLists Dynamic In MVC 4 Form

Vous devez créer un appel ajax dans l'événement de modification de la province ddl . Cet appel demande une action et renvoie les villes de la province sélectionnée.

$("province_dll").change(function(){
    $.ajax({
         url: 'getCitiesController/getCitiesAction',
         type: 'post',
         data: {
               provinceId: provinceIdVar
         }
    }).done(function(response){
         $("cities_dll").html(response);
    }); 
});

Dans l'action:

[HttpPost]
public ActionResult getCicitesAction(int provinceId)
{
     var cities = db.cities.Where(a => a.provinceId == provinceId).Select(a => "<option value='" + a.cityId + "'>" + a.cityName + "'</option>'";

     return Content(String.Join("", cities));
}
4

Rendons les choses plus simples

  • Étape 1: Fonction/données côté serveur

    public JsonResult FetchP(string O)
    {
        List<SelectListItem> PList = new List<SelectListItem>();
         PList = _PService.GetAllPActive()
                  .Select(i => new SelectListItem()
                             {
                                 Text = i.PName,
                                 Value = i.PID                                   
                             }).ToList();
    
        return Json(PList, JsonRequestBehavior.AllowGet);
    }
    
  • Étape 2: interpréteur de fonction/données côté client

    function FetchP()
    {
        var url = '@Url.Action("FetchP", "Your_Controller")'; 
        var PDD= $("#PDD");
        var ODD= $("#ODD").val(); 
    
        $.getJSON(url, { O: ODD}, function (response) {
            PDD.empty(); 
            debugger;
            $.each(response, function (index, item) {
                debugger;
                var p = new Option(item.Text, item.Value);
                PDD.append(p);
            });
        });
    }
    
  • Étape 3: appel - fonction côté client/démarrage

  • Liste 1:

    @Html.DropDownList("ODD", ViewBag.OList as IEnumerable<SelectListItem>, new { @id = "ODD", @class = "form-control", @onchange= "FetchP()" })
    
  • Liste 2:

    @Html.DropDownList("PDD", ViewBag.PList as IEnumerable<SelectListItem>,new { @id = "PDD", @class = "form-control"})
    
1
Kedar9444