2015-01-23 63 views
5

İki DropDownLists içeren bir görünüm oluşturmaya çalışıyorum. İkinci DropDownList'te bulunan seçenekler, kullanıcının önce seçtiği şeye bağlıdır. şöyle ben ViewBag içinde Bence bu verileri geçiyorum:MVC 4 Razor - Dinamik bir DropDownList oluşturma

List<SelectListItem> firstBoxChoices = ViewBag.firstBoxChoices; 
    Dictionary<string, List<SelectListItem>> secondBoxDict = ViewBag.secondBoxDict; 

ilk nesne ilk DropDownList için seçeneği vardır. Kullanıcı bunlardan birini seçtiğinde, ikinci DropDownList için sözlüğümden uygun seçenekler listesini almam gerekir. Bunu nasıl başaracağımı anlayamıyorum. Bir Javascript onchange() işlevinde ilk DropDownList öğesinin yeni seçimini alırsam, bu değeri C# sözlüğümün anahtarı olarak kullanmanın herhangi bir yolu yoktur.

Elbette, bu işlevselliği web'de görmüştüm, bu yüzden bir şekilde mümkün olduğunu biliyorum. Bunu nasıl başarabilirim?

Teşekkürler!

cevap

7

Modeldeki olası tüm veri öğelerini depolamanızı zorlamadan bunu yapmanın birkaç yolu vardır, tercihim Javascript/JQuery'yi kullanmaktır. İşte Ülke/Eyalet kaskatlama bir örnektir açılır:

<script type="text/javascript"> 
    function AppendUrlParamTokens(url, params) { 

     for (var param in params) { 
      if (params[param] == null) { 
       delete params[param]; 
      } 
     } 

     return url + "?" + jQuery.param(params); 
    } 

    function OnCountriesChange(ddl) { 
     jQuery.getJSON(AppendUrlParamTokens('@Url.Action("GetStates", "Data")', { countryId: ddl.options[ddl.selectedIndex].value }), function (result) { 
      var target = jQuery('#states_ddl'); 
      target.empty(); 
      jQuery(result).each(function() { 
       jQuery(document.createElement('option')) 
        .attr('value', this.Value) 
        .text(this.Text) 
        .appendTo(target); 
      }); 
     }); 
    }; 
</script> 

Ülke açılır:

@Html.DropDownListFor(model => model.Country, new SelectList(Model.Countries, "Value", "Text", Model.PreviousCountrySelected), "(Select One)", new { id = "countries_ddl", onchange = "OnCountriesChange(this)" }) 

Devlet açılır:

bir ülke seçildiğinde

JavaScript durumlarını elde etmek için kullanılan

Html.DropDownListFor(model => model.State, 
           Model.States != null 
             ? new SelectList(Model.States, "Value", "Text", Model.PreviousStateSelected) 
             : new SelectList(new List<SelectListItem>(), "Value", "Text"), 
           new { id = "states_ddl" }) 

Durumları almak için denetleyici yöntemi:

public ActionResult GetStates(short? countryId) 
{ 
    if (!countryId.HasValue) 
    { 
     return Json(new List<object>(), JsonRequestBehavior.AllowGet); 
    } 

    var data = GetAllStatesForCountry(countryId.Value).Select(o => new { Text = o.StateName, Value = o.StateId }); 

    return Json(data, JsonRequestBehavior.AllowGet); 
} 

Buradaki fikir, açılır listenin 1 seçiminde, ikinci açılır öğenizin değerini almak için ajax kullanır.

Düzenleme: inşa URL'ler

+0

aşağıdaki görünüm modeli

public class MyModel { [Required(ErrorMessage = "Please select an organisation")] [Display(Name = "Organisation")] public int? SelectedOrganisation { get; set; } [Required(ErrorMessage = "Please select an employee")] [Display(Name = "Employee")] public int? SelectedEmployee { get; set; } public SelectList OrganisationList { get; set; } public SelectList EmployeeList { get; set; } } 

Verilen Bu benim aradığımı adildir! Teşekkürler. –

3

seçilen değere bağlı olarak opsiyon verilerini döndüren bir sunucu yöntemini çağırarak ikinci seçme doldurmak gerekir ilk select ait .change olay için yarar yöntemini belirtmeyi unuttum. Kontrolör

public ActionResult Edit(int ID) 
{ 
    MyModel model = new MyModel(); 
    model.SelectedOrganisation = someValue; // set if appropriate 
    model.SelectedEmployee = someValue; // set if appropriate 
    ConfigureEditModel(model); // populate select lists 
    return View(model); 
} 

[HttpPost] 
public ActionResult Edit(MyModel model) 
{ 
    if(!ModelState.IsValid) 
    { 
    ConfigureEditModel(model); // reassign select lists 
    return View(model); 
    } 
    // save and redirect 
} 

private void ConfigureEditModel(MyModel model) 
{ 
    // populate select lists 
    model.OrganisationList = new SelectList(db.Organisations, "ID", "Name"); 
    if(model.SelectedOrganisation.HasValue) 
    { 
    var employees = db.Employees.Where(e => e.Organisation == model.SelectedOrganisation.Value); 
    model.EmployeeList = new SelectList(employees, "ID", 
    } 
    else 
    { 
    model.EmployeeList = new SelectList(Enumerable.Empty<SelectListItem>()); 
    } 
} 

[HttpGet] 
public JsonResult FetchEmployees(int ID) 
{ 
    var employees = db.Employees.Where(e => e.Organisation == ID).Select(e => new 
    { 
    ID = e.ID, 
    Name = e.Name 
    }); 
    return Json(employees, JsonRequestBehavior.AllowGet); 
} 

Görünüm

@model MyModel 
.... 
    @Html.LabelFor(m => m.SelectedOrganisation) 
    @Html.DropDownListFor(m => m.SelectedOrganisation, Model.OrganisationList, "-Please select-") 
    @Html.ValidationMessageFor(m => m.SelectedOrganisation) 
    @Html.LabelFor(m => m.SelectedEmployee) 
    @Html.DropDownListFor(m => m.SelectedEmployee, Model.EmployeeList, "-Please select-") 
    @Html.ValidationMessageFor(m => m.SelectedEmployee) 
.... 

Senaryo

var url = '@Url.Action("FetchEmployees")'; 
var employees = $('SelectedEmployee'); 
$('#SelectedOrganisation').change(function() { 
    employees.empty(); 
    if(!$(this).val()) { 
    return; 
    } 
    employees.append($('<option></option>').val('').text('-Please select-')); 
    $.getJson(url, { ID: $(this).val() }, function(data) { 
    $.each(data, function(index, item) { 
     employees.append($('<option></option>').val(item.ID).text(item.Text)); 
    }); 
    }); 
}); 
+0

Ayrıca harika bir cevap. Teşekkürler! –

İlgili konular