www update tutorial tools sintaxis packs net mvc4 mvc language instalar asp asp.net-mvc asp.net-mvc-3 razor

asp.net-mvc - update - sintaxis razor mvc 5



Desplegable en cascada en MVC 3 Razor view (5)

Gracias por su iniciativa. Me ayudó enormemente llegar al punto. Pero como se mencionó ''xxviktor'', obtuve la referencia circular. error. Para deshacerme de él, lo hice de esta manera.

public string GetCounties(int countryID) { List<County> objCounties = new List<County>(); var objResp = _mastRepo.GetCounties(countryID, ref objCounties); var objRetC = from c in objCounties select new SelectListItem { Text = c.Name, Value = c.ID.ToString() }; return new JavaScriptSerializer().Serialize(objRetC); }

Y para lograr la cascada automática, extendí ligeramente la extensión jQuery de esta manera.

$(''#ddlCountry'').cascade({ url: ''@Url.Action("GetCounties")'', paramName: ''countryID'', childSelect: $(''#ddlState''), childCascade: true });

Y el JS real está utilizando este parámetro como a continuación (dentro de la solicitud JSON).

// trigger child change if (opts.childCascade) { opts.childSelect.change(); }

Espero que esto ayude a alguien con un problema similar.

Estoy interesado en cómo implementar listas desplegables en cascada para las direcciones en una vista Razor. Mi entidad de sitio tiene una propiedad Suburbio. El suburbio tiene CityId y City tiene ProvinceId. Me gustaría mostrar los menús desplegables para todos los suburbios, ciudades y provincias en la vista del sitio, donde, por ejemplo, el menú desplegable del barrio mostrará inicialmente "Primero seleccione una ciudad", y el menú desplegable Ciudad, "Primero seleccione una provincia". Al seleccionar una provincia, las ciudades de la provincia están pobladas, etc.

¿Cómo puedo conseguir esto? ¿Dónde empiezo?


Para implementar listas desplegables en cascada que admitan la validación y el enlace incorporados de MVC, deberá hacer algo un poco diferente de lo que se hace en las otras respuestas aquí.

Si su modelo tiene validación, esto lo apoyará. Un extracto de un modelo con validación:

[Required] [DisplayFormat(ConvertEmptyStringToNull = false)] public Guid cityId { get; set; }

En su controlador necesita agregar un método get, para que su vista pueda obtener los datos relevantes más adelante:

[AcceptVerbs(HttpVerbs.Get)] public JsonResult GetData(Guid id) { var cityList = (from s in db.City where s.stateId == id select new { cityId = s.cityId, name = s.name }); //simply grabbing all of the cities that are in the selected state return Json(cityList.ToList(), JsonRequestBehavior.AllowGet); }

Ahora, a la Vista que mencioné anteriormente:

En su opinión, tiene dos menús desplegables similares a esto:

<div class="editor-label"> @Html.LabelFor(model => model.stateId, "State") </div> <div class="editor-field"> @Html.DropDownList("stateId", String.Empty) @Html.ValidationMessageFor(model => model.stateId) </div> <div class="editor-label"> @Html.LabelFor(model => model.cityId, "City") </div> <div class="editor-field"> @*<select id="cityId"></select>*@ @Html.DropDownList("cityId", String.Empty) @Html.ValidationMessageFor(model => model.cityId) </div>

El contenido del menú desplegable está vinculado por el controlador y se completa automáticamente. Nota: en mi experiencia al eliminar este enlace y confiar en el script java para rellenar los menús desplegables, pierdes la validación. Además, la forma en que estamos vinculados aquí juega bien con la validación, por lo que no hay ninguna razón para cambiarla.

Ahora en nuestro plugin jQuery:

(function ($) { $.fn.cascade = function (secondaryDropDown, actionUrl, stringValueToCompare) { primaryDropDown = this; //This doesn''t necessarily need to be global globalOptions = new Array(); //This doesn''t necessarily need to be global for (var i = 0; i < secondaryDropDown.options.length; i++) { globalOptions.push(secondaryDropDown.options[i]); } $(primaryDropDown).change(function () { if ($(primaryDropDown).val() != "") { $(secondaryDropDown).prop(''disabled'', false); //Enable the second dropdown if we have an acceptable value $.ajax({ url: actionUrl, type: ''GET'', cache: false, data: { id: $(primaryDropDown).val() }, success: function (result) { $(secondaryDropDown).empty() //Empty the dropdown so we can re-populate it var dynamicData = new Array(); for (count = 0; count < result.length; count++) { dynamicData.push(result[count][stringValueToCompare]); } //allow the empty option so the second dropdown will not look odd when empty dynamicData.push(globalOptions[0].value); for (var i = 0; i < dynamicData.length; i++) { for (var j = 0; j < globalOptions.length; j++) { if (dynamicData[i] == globalOptions[j].value) { $(secondaryDropDown).append(globalOptions[j]); break; } } } }, dataType: ''json'', error: function () { console.log("Error retrieving cascading dropdown data from " + actionUrl); } }); } else { $(secondaryDropDown).prop(''disabled'', true); } secondaryDropDown.selectedindex = 0; //this prevents a previous selection from sticking }); $(primaryDropDown).change(); }; } (jQuery));

Puede copiar el jQuery anterior que creé, en etiquetas <script>...</script> en su vista, o en un archivo de script separado si lo desea (nota que actualicé esto para hacerlo cruzar navegador, sin embargo, el escenario en que ya estaba usando, ya no es necesario, debería funcionar, sin embargo).

En esas mismas etiquetas de script, (no en un archivo separado) puede llamar al complemento utilizando el siguiente javascript:

$(document).ready(function () { var primaryDropDown = document.getElementById(''stateId''); var secondaryDropdown = document.getElementById(''cityId''); var actionUrl = ''@Url.Action("GetData")'' $(primaryDropDown).cascade(secondaryDropdown, actionUrl); });

Recuerde agregar la parte $(document).ready , la página debe estar completamente cargada antes de intentar hacer la cascada de desplegable.


Vamos a ilustrar con un ejemplo. Como siempre comienza con un modelo:

public class MyViewModel { public string SelectedProvinceId { get; set; } public string SelectedCityId { get; set; } public string SelectedSuburbId { get; set; } public IEnumerable<Province> Provinces { get; set; } } public class Province { public string Id { get; set; } public string Name { get; set; } }

Luego un controlador:

public class HomeController : Controller { public ActionResult Index() { var model = new MyViewModel { // TODO: Fetch those from your repository Provinces = Enumerable.Range(1, 10).Select(x => new Province { Id = (x + 1).ToString(), Name = "Province " + x }) }; return View(model); } public ActionResult Suburbs(int cityId) { // TODO: Fetch the suburbs from your repository based on the cityId var suburbs = Enumerable.Range(1, 5).Select(x => new { Id = x, Name = "suburb " + x }); return Json(suburbs, JsonRequestBehavior.AllowGet); } public ActionResult Cities(int provinceId) { // TODO: Fetch the cities from your repository based on the provinceId var cities = Enumerable.Range(1, 5).Select(x => new { Id = x, Name = "city " + x }); return Json(cities, JsonRequestBehavior.AllowGet); } }

Y finalmente una vista:

@model SomeNs.Models.MyViewModel @{ ViewBag.Title = "Home Page"; } <script type="text/javascript" src="/scripts/jquery-1.4.4.js"></script> <script type="text/javascript"> $(function () { $(''#SelectedProvinceId'').change(function () { var selectedProvinceId = $(this).val(); $.getJSON(''@Url.Action("Cities")'', { provinceId: selectedProvinceId }, function (cities) { var citiesSelect = $(''#SelectedCityId''); citiesSelect.empty(); $.each(cities, function (index, city) { citiesSelect.append( $(''<option/>'') .attr(''value'', city.Id) .text(city.Name) ); }); }); }); $(''#SelectedCityId'').change(function () { var selectedCityId = $(this).val(); $.getJSON(''@Url.Action("Suburbs")'', { cityId: selectedCityId }, function (suburbs) { var suburbsSelect = $(''#SelectedSuburbId''); suburbsSelect.empty(); $.each(suburbs, function (index, suburb) { suburbsSelect.append( $(''<option/>'') .attr(''value'', suburb.Id) .text(suburb.Name) ); }); }); }); }); </script> <div> Province: @Html.DropDownListFor(x => x.SelectedProvinceId, new SelectList(Model.Provinces, "Id", "Name")) </div> <div> City: @Html.DropDownListFor(x => x.SelectedCityId, Enumerable.Empty<SelectListItem>()) </div> <div> Suburb: @Html.DropDownListFor(x => x.SelectedSuburbId, Enumerable.Empty<SelectListItem>()) </div>

Como mejora, el código de javascript podría acortarse escribiendo un complemento de jquery para evitar la duplicación de algunas partes.

ACTUALIZAR:

Y hablando de un complemento, podrías tener algo entre líneas:

(function ($) { $.fn.cascade = function (options) { var defaults = { }; var opts = $.extend(defaults, options); return this.each(function () { $(this).change(function () { var selectedValue = $(this).val(); var params = { }; params[opts.paramName] = selectedValue; $.getJSON(opts.url, params, function (items) { opts.childSelect.empty(); $.each(items, function (index, item) { opts.childSelect.append( $(''<option/>'') .attr(''value'', item.Id) .text(item.Name) ); }); }); }); }); }; })(jQuery);

Y luego simplemente conectarlo:

$(function () { $(''#SelectedProvinceId'').cascade({ url: ''@Url.Action("Cities")'', paramName: ''provinceId'', childSelect: $(''#SelectedCityId'') }); $(''#SelectedCityId'').cascade({ url: ''@Url.Action("Suburbs")'', paramName: ''cityId'', childSelect: $(''#SelectedSuburbId'') }); });



<script src="~/Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript"> $(document).ready(function () { //Dropdownlist Selectedchange event $("#country").change(function () { $("#State").empty(); $.ajax({ type: ''POST'', url: ''@Url.Action("State")'', // we are calling json method dataType: ''json'', data: { id: $("#country").val() }, // here we are get value of selected country and passing same value success: function (states) { // states contains the JSON formatted list // of states passed from the controller $.each(states, function (i, state) { $("#State").append(''<option value="'' + state.Value + ''">'' + state.Text + ''</option>''); // here we are adding option for States }); }, error: function (ex) { alert(''Failed to retrieve states.'' + ex); } }); return false; }) }); </script>

<div> @Html.DropDownList("country", ViewBag.country as List<SelectListItem>, "CountryName", new { style = "width: 200px;" }) </div> <div> </div> <div> @Html.DropDownList("State", ViewBag.country as List<SelectListItem>) </div>

Desde el controlador obtengo los valores

public async Task<ActionResult> Country() { Country co = new Country(); List<SelectListItem> li = new List<SelectListItem>(); li.Add(new SelectListItem { Text = "Select", Value = "0" }); li.Add(new SelectListItem { Text = "India", Value = "1" }); li.Add(new SelectListItem { Text = "Nepal", Value = "2" }); li.Add(new SelectListItem { Text = "USA", Value = "3" }); li.Add(new SelectListItem { Text = "Kenya", Value = "4" }); ; ViewBag.country= li; return View(); } public JsonResult state(string id) { List<SelectListItem> states = new List<SelectListItem>(); states.Add(new SelectListItem { Text = "--Select State--", Value = "0" }); switch (id) { case "1": states.Add(new SelectListItem { Text = "MP", Value = "1" }); states.Add(new SelectListItem { Text = "UP", Value = "2" }); break; case "3": states.Add(new SelectListItem { Text = "USA1", Value = "3" }); states.Add(new SelectListItem { Text = "USA2", Value = "4" }); break; } return Json(new SelectList(states, "Value", "Text", JsonRequestBehavior.AllowGet)); }