2012-04-24 33 views
11

Soy muy nuevo en ASP.NET y estoy usando el framework MVC 3 de ASP.Net. Estaba intentando filtrar las opciones de una lista desplegable usando otro menú desplegable y no puedo hacer eso. Intenté hacer esto primero completando la lista de categorías principales y subcategorías y cargándolas en la página. Luego establezco el atributo de clase de las opciones de cada subcategoría en su categoría principal. Finalmente, al hacer clic en la categoría principal de la primera lista desplegable, solo se muestra la subcategoría secundaria y se oculta el resto (así es como lo hice anteriormente en Java). Pero en ASP.Net MVC, el código html es tan diferente que ni siquiera puedo configurar el atributo de clase para cada opción del menú desplegable, generalmente establece la clase para todos los menús desplegables, no para cada opción. Esto es lo que tengo en este momento Este es mi punto de vistaCómo filtrar las opciones de una lista desplegable usando otra lista desplegable

<p> 
@Html.LabelFor(model => model.CategoryId) 
@Html.DropDownListFor(x => x.CategoryId , new SelectList(Model.Categories, "CategoryId", "CategoryName"), new { onchange= "this.form.submit();"}) 
</p> 

<p> 
@Html.LabelFor(model => model.SubCategories) 
@Html.DropDownListFor(x => x.SubCategories, new SelectList(Model.SubCategories, "SubCategoryId", "SubCategoryName"), new { @class = "Category1.categoryname" }) 
</p> 

Ésta es mi modelo

public class TestQuestionsViewModel 
{ 
    public string CategoryId { get; set; } 
    public IEnumerable<Category> Categories { get; set; } 

    public string SubCategoryId { get; set; } 
    public IEnumerable<SubCategory> SubCategories { get; set; } 
} 

Este es mi método de la clase controlador

public ActionResult Create() 
    { 

     var model = new TestQuestionsViewModel 
     { 

      Categories = resetDB.Categories.OrderBy(c => c.categoryid), 
      SubCategories = resetDB.SubCategories.OrderBy(sc => sc.subcategoryid) 
     }; 
    return View(model); 
    } 

Mi pregunta es ¿Cómo puedo establecer los atributos de clase para cada opción individual. O si alguien tiene una sugerencia sobre cómo hacer esto de una manera diferente, estoy abierto a cualquier solución. Gracias.

Respuesta

24

Cargando todos los elementos secundarios a la página cuando la página se carga inicialmente, no parece ser una buena idea para mí. ¿Qué pasa si tiene 100 categorías y cada categoría tiene 200 elementos de sub categoría? ¿De verdad quieres cargar 20000 artículos?

Creo que deberías hacer una forma incremental de carga. Proporcione el menú desplegable Categoría principal con los valores, Permitir que el usuario seleccione un elemento de eso. Realice una llamada al Servidor y obtenga las categorías Sub que pertenece a la categoría seleccionada y cargue esos datos en el segundo menú desplegable. Puede usar jQuery ajax para hacerlo de modo que el usuario no sienta una nueva página completa cuando selecciona un menú desplegable. Así es como lo haré.

Crear el modelo de vista que tiene tanto propiedades de categoría de

public class ProductViewModel 
{ 
    public int ProductId { set;get;} 
    public IEnumerable<SelectListItem> MainCategory { get; set; } 
    public string SelectedMainCatId { get; set; } 
    public IEnumerable<SelectListItem> SubCategory { get; set; } 
    public string SelectedSubCatId { get; set; } 
} 

Deje que su método GET acción devuelve este punto de vista inflexible con el contenido para MainCategory lleno

public ActionResult Edit() 
{ 
    var objProduct = new ProductViewModel();    
    objProduct.MainCategory = new[] 
    { 
     new SelectListItem { Value = "1", Text = "Perfume" }, 
     new SelectListItem { Value = "2", Text = "Shoe" }, 
     new SelectListItem { Value = "3", Text = "Shirt" } 
    }; 
    objProduct.SubCategory = new[] { new SelectListItem { Value = "", Text = "" } }; 
    return View(objProduct); 
} 

y en su inflexible Ver,

@model MvcApplication1.Models.ProductViewModel 
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 
@using (Html.BeginForm()) 
{  
    @Html.DropDownListFor(x => x.SelectedMainCatId, new SelectList(Model.MainCategory,"Value","Text"), "Select Main..") 
    @Html.DropDownListFor(x => x.SelectedSubCatId, new SelectList(Model.SubCategory, "Value", "Text"), "Select Sub..")  
    <button type="submit">Save</button> 
} 
<script type="text/javascript"> 
    $(function() { 
     $("#SelectedMainCatId").change(function() { 
      var val = $(this).val(); 
      var subItems=""; 
      $.getJSON("@Url.Action("GetSub","Product")", {id:val} ,function (data) { 
       $.each(data,function(index,item){ 
       subItems+="<option value='"+item.Value+"'>"+item.Text+"</option>" 
       }); 
       $("#SelectedSubCatId").html(subItems) 
      }); 
     }); 
    }); 
</script> 

Agregue el método de acción GetSub a su estafa Troller para devolver las subcategorías para la categoría seleccionada.Estamos volviendo la respuesta JSON

public ActionResult GetSub(int id) 
{ 
    List<SelectListItem> items = new List<SelectListItem>(); 
    items.Add(new SelectListItem() { Text = "Sub Item 1", Value = "1" }); 
    items.Add(new SelectListItem() { Text = "Sub Item 2", Value = "8"}); 
    // you may replace the above code with data reading from database based on the id 

    return Json(items, JsonRequestBehavior.AllowGet); 
} 

Ahora los valores seleccionados estarán disponibles en su método de acción HTTPOST

[HttpPost] 
    public ActionResult Edit(ProductViewModel model) 
    { 
     // You have the selected values here in the model. 
     //model.SelectedMainCatId has value! 
    } 
+0

Olvidé agradecerte @Shyju ... esto funciona genial muchas gracias. Lo he usado y funciona muy bien. Además, me ayudó a investigar más sobre Json y Ajax. – Sophonias

+0

@Sophonias: De nada. Me alegro de poder ayudar. – Shyju

+0

necesita entender el código interno en el resultado de la acción de edición –

0

Necesita agregar otro método para manejar la devolución de datos y filtrar las opciones de la subcategoría. Algo como esto:

[HttpPost] 
public ActionResult Create(TestQuestionsViewModel model) 
{ 
    model.SubCategories = resetDB.SubCategories 
      .Where(sc => sc.categoryid == model.SubCategoryId) 
      .OrderBy(sc => sc.subcategoryid); 
    return View(model);  
} 

Editar

Por cierto, si usted todavía tiene que establecer el nombre de la clase a la otra desplegable, puede no hacerlo así. La manera más fácil sería agregar una propiedad "SelectedCategoryName" a su modelo, y referencia como {@class = ModelSelectedCategoryName}.

+0

donde esa voluntad sucedió en el lado del servidor o del lado del cliente? –

Cuestiones relacionadas