2010-11-10 4 views
11

Me pregunto si alguien puede arrojar algo de luz sobre este problema ..optgroup desplegable apoyo en MVC - Problemas con el modelo de unión

Tengo un desplegable grupo de opciones para seleccionar el origen étnico de una persona - sin embargo es no almacenando el valor en el modelo.

modelo de vista

[UIHint("EthnicOriginEditorTemplate")] 
    [DisplayName("Question 6: Ethnic Origin")] 
    public int EthnicOrigin { get; set; } 

Helper: GroupDropList.Cs

using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web.Mvc; 
using System.Web.Routing; 

namespace Public.Helpers 
{ 
    public static class GroupDropListExtensions 
    { 
     public static string GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int SelectedValue, object htmlAttributes) 
     { 
      if (data == null && helper.ViewData != null) 
       data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>; 
      if (data == null) return string.Empty; 

      var select = new TagBuilder("select"); 

      if (htmlAttributes != null) 
       select.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 

      select.GenerateId(name); 

      var optgroupHtml = new StringBuilder(); 
      var groups = data.ToList(); 
      foreach (var group in data) 
      { 
       var groupTag = new TagBuilder("optgroup"); 
       groupTag.Attributes.Add("label", helper.Encode(group.Name)); 
       var optHtml = new StringBuilder(); 
       foreach (var item in group.Items) 
       { 
        var option = new TagBuilder("option"); 
        option.Attributes.Add("value", helper.Encode(item.Value)); 
        if (SelectedValue != 0 && item.Value == SelectedValue) 
         option.Attributes.Add("selected", "selected"); 
        option.InnerHtml = helper.Encode(item.Text); 
        optHtml.AppendLine(option.ToString(TagRenderMode.Normal)); 
       } 
       groupTag.InnerHtml = optHtml.ToString(); 
       optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal)); 
      } 
      select.InnerHtml = optgroupHtml.ToString(); 
      return select.ToString(TagRenderMode.Normal); 
     } 
    } 

    public class GroupDropListItem 
    { 
     public string Name { get; set; } 
     public List<OptionItem> Items { get; set; } 
    } 

    public class OptionItem 
    { 
     public string Text { get; set; } 
     public int Value { get; set; } 
    } 
} 

Esta es mi EditorTemplate

<%@ Import Namespace="Public.Helpers"%> 
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<int>"%> 

<%=Html.GroupDropList("EthnicOrigin", 
           new[] 
            {           
             new GroupDropListItem 
              { 
               Name = "Ethnicity", 
               Items = new List<OptionItem> 
                 { 
                  new OptionItem {Value = 0, Text = "Please Select"} 
                 } 
              }, 

             new GroupDropListItem 
              { 
               Name = "a) White", 
               Items = new List<OptionItem> 
                 { 
                  new OptionItem {Value = 1, Text = "British"}, 
                  new OptionItem {Value = 2, Text = "Irish"}, 
                  new OptionItem {Value = 3, Text = "Other White (Please specify below)"} 
                 } 
              }, 

             --snip 

            }, Model, null)%> 

Y en la vista que estoy referencia a ella como:

<%=Html.EditorFor(x => x.EthnicOrigin, "EthnicOriginEditorTemplate")%> 

Sin embargo, no está pasando por el valor seleccionado en el modelo ... ¿alguien ha experimentado problemas similares ... muchas gracias de antemano por algunos indicadores .

+0

Sólo una nota - También he intentado esto con cadena en lugar de int como el valor de la opción y todavía no se une. – beebul

+0

Por favor, compruebe [ahora Soporte para Optgroup en la lista desplegable .Net MVC] (http://www.jquery2dotnet.com/2014/01/html5-dropdownlist-optgroup-tag-in-mvc.html) – Sender

Respuesta

8

Su select no tiene un atributo name por lo que cuando envía el formulario, el valor seleccionado no se envía al servidor. Necesita agregar un nombre:

select.GenerateId(name); 
select.MergeAttribute("name", name); 
+0

Muchas gracias Darin - funcionó Un dulce... :-) – beebul

5

Acabo de cambiar la clase de ayuda para hacer que funcione para MVC 3 y con int nullable. Muchas gracias por la clase, me ahorra mucho tiempo.

public static class GroupDropListExtensions 
{ 
    public static MvcHtmlString GroupDropList(this HtmlHelper helper, string name, IEnumerable<GroupDropListItem> data, int? SelectedValue, object htmlAttributes) 
    { 
     if (data == null && helper.ViewData != null) 
      data = helper.ViewData.Eval(name) as IEnumerable<GroupDropListItem>; 
     if (data == null) return new MvcHtmlString(string.Empty); 

     var select = new TagBuilder("select"); 

     if (htmlAttributes != null) 
      select.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 

     select.GenerateId(name); 
     select.MergeAttribute("name", name); 

     var optgroupHtml = new StringBuilder(); 
     var groups = data.ToList(); 
     foreach (var group in data) 
     { 
      var groupTag = new TagBuilder("optgroup"); 
      groupTag.Attributes.Add("label", helper.Encode(group.Name)); 
      var optHtml = new StringBuilder(); 
      foreach (var item in group.Items) 
      { 
       var option = new TagBuilder("option"); 
       option.Attributes.Add("value", helper.Encode(item.Value)); 
       if (SelectedValue != 0 && item.Value == SelectedValue) 
        option.Attributes.Add("selected", "selected"); 
       option.InnerHtml = helper.Encode(item.Text); 
       optHtml.AppendLine(option.ToString(TagRenderMode.Normal)); 
      } 
      groupTag.InnerHtml = optHtml.ToString(); 
      optgroupHtml.AppendLine(groupTag.ToString(TagRenderMode.Normal)); 
     } 
     select.InnerHtml = optgroupHtml.ToString(); 
     return new MvcHtmlString(select.ToString(TagRenderMode.Normal)); 
    } 
} 

public class GroupDropListItem 
{ 
    public string Name { get; set; } 
    public List<OptionItem> Items { get; set; } 
} 

public class OptionItem 
{ 
    public string Text { get; set; } 
    public int Value { get; set; } 
} 
1

Esta es soportado de forma nativa utilizando como SelectListGroup de ASP.NET MVC 5.2:

var items = new List<SelectListItem>(); 
var group1 = new SelectListGroup() { Name = "Group 1" }; 
items.Add(new SelectListItem() { Text = "Item1", Group = group1 }); 

Luego, en MVC, hacer

@Html.DropDownList("select", items) 
Cuestiones relacionadas