2012-10-09 28 views
15

Soy bastante nuevo en el mundo MVC de ASP.net y estoy tratando de encontrar la manera de renderizar un grupo de casillas de verificación que son fuertemente tipeado a un modelo de vista. En webforms solo usaría el control checkboxlist, pero estoy un poco perdido con MVC.Cómo renderizo un grupo de casillas de verificación usando MVC 4 y modelos de vista (fuertemente tipados)

Estoy construyendo un formulario de contacto simple para una empresa de planificación de bodas y necesito pasar cualquier valor de casilla de verificación que el usuario seleccione a mi controlador.

La forma casillas de verificación deben tener este aspecto: enter image description here

Su ayuda sería muy apreciada. ¡Gracias!

Esto es lo que tengo hasta ahora.

CONTROLADOR

[HttpPost] 
public ActionResult Contact(ContactViewModel ContactVM) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(ContactVM); 
    } 
    else 
    { 
     //Send email logic 

     return RedirectToAction("ContactConfirm"); 
    } 
} 

vista del modelo

public class ContactViewModel 
{ 
    [Required] 
    public string Name { get; set; } 

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

    [Required] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    [Required] 
    public string Subject { get; set; } 
    public IEnumerable<SelectListItem> SubjectValues 
    { 
     get 
     { 
      return new[] 
      { 
       new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" }, 
       new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" }, 
       new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" }, 
       new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" } 
      }; 
     } 
    } 


    //Not sure what I should do for checkboxes... 

} 

VISTA

@model NBP.ViewModels.ContactViewModel 

@{ 
    ViewBag.Title = "Contact"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

@using (Html.BeginForm()) 
{ 
    <div id="ContactContainer"> 
     <div><span class="RequiredField">*&nbsp;</span>Your Name:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Name) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Phone) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Email:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Email) 
     </div> 
     <div>Subject:</div> 
     <div> 
      @Html.DropDownListFor(model => model.Subject, Model.SubjectValues) 
     </div> 
     <div>Vendor Assistance:</div> 
     <div> 

      <!-- CHECKBOXES HERE --> 

     </div> 
     <div> 
      <input id="btnSubmit" type="submit" value="Submit" /> 
     </div> 
    </div> 
} 
+0

Tengo curiosidad ... ¿Incluso trataste de escribir Html.Check ...? –

+1

sí, pero no estoy seguro de cómo los conectaría con mi modelo de vista ... – Maddhacker24

Respuesta

15

Se podría enriquecer su vista del modelo:

public class VendorAssistanceViewModel 
{ 
    public string Name { get; set; } 
    public bool Checked { get; set; } 
} 

public class ContactViewModel 
{ 
    public ContactViewModel() 
    { 
     VendorAssistances = new[] 
     { 
      new VendorAssistanceViewModel { Name = "DJ/BAND" }, 
      new VendorAssistanceViewModel { Name = "Officiant" }, 
      new VendorAssistanceViewModel { Name = "Florist" }, 
      new VendorAssistanceViewModel { Name = "Photographer" }, 
      new VendorAssistanceViewModel { Name = "Videographer" }, 
      new VendorAssistanceViewModel { Name = "Transportation" }, 
     }.ToList(); 
    } 

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

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

    [Required] 
    [DataType(DataType.EmailAddress)] 
    public string Email { get; set; } 

    [Required] 
    public string Subject { get; set; } 
    public IEnumerable<SelectListItem> SubjectValues 
    { 
     get 
     { 
      return new[] 
      { 
       new SelectListItem { Value = "General Inquiry", Text = "General Inquiry" }, 
       new SelectListItem { Value = "Full Wedding Package", Text = "Full Wedding Package" }, 
       new SelectListItem { Value = "Day of Wedding", Text = "Day of Wedding" }, 
       new SelectListItem { Value = "Hourly Consultation", Text = "Hourly Consultation" } 
      }; 
     } 
    } 

    public IList<VendorAssistanceViewModel> VendorAssistances { get; set; } 
} 

controlador:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new ContactViewModel()); 
    } 

    [HttpPost] 
    public ActionResult Index(ContactViewModel model) 
    { 
     if (!ModelState.IsValid) 
     { 
      return View(model); 
     } 

     //Send email logic 
     return RedirectToAction("ContactConfirm"); 
    } 
} 

Vista:

@using (Html.BeginForm()) 
{ 
    <div id="ContactContainer"> 
     <div><span class="RequiredField">*&nbsp;</span>Your Name:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Name) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Phone:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Phone) 
     </div> 
     <div><span class="RequiredField">*&nbsp;</span>Your Email:</div> 
     <div> 
      @Html.TextBoxFor(model => model.Email) 
     </div> 
     <div>Subject:</div> 
     <div> 
      @Html.DropDownListFor(model => model.Subject, Model.SubjectValues) 
     </div> 
     <div>Vendor Assistance:</div> 
     <div> 
      @for (int i = 0; i < Model.VendorAssistances.Count; i++) 
      { 
       <div> 
        @Html.HiddenFor(x => x.VendorAssistances[i].Name) 
        @Html.CheckBoxFor(x => x.VendorAssistances[i].Checked) 
        @Html.LabelFor(x => x.VendorAssistances[i].Checked, Model.VendorAssistances[i].Name) 
       </div> 
      } 
     </div> 
     <div> 
      <input id="btnSubmit" type="submit" value="Submit" /> 
     </div> 
    </div> 
} 
+1

Hola Darin, creo que estoy cerca, pero cuando trato de acceder a los campos marcados desde mi controlador no obtengo los valores correctos. Estoy haciendo bucles usando: foreach (var Vendor en ContactVM.VendorAssistances). El proveedor está saliendo como NBP.ViewModels.VendorAssistanceViewModel. ¿Alguna idea? – Maddhacker24

+1

Bueno, es bastante normal que el proveedor salga como 'VendorAssistanceViewModel'. Después de todo, la propiedad 'VendorAssistances' se define como' IList '. Podrías profundizar un poco más para ver el 'Nombre' y las propiedades' Comprobadas': 'Vendor.Name' y' Vendor.Checked'. –

+1

Gracias Darin, que hizo el truco. ¡Tonto de mí! – Maddhacker24

1

Utilice una matriz de cadenas en su modelo de vista. Entonces puedes usar el ayudante que pirateé. si no quiere usar el helper y la enumeración, entonces vea el HTML real en la parte inferior. El archivador devolverá una matriz de cadenas con solo los valores de cadena seleccionados en ella. si no se selecciona ninguno, devuelve un valor nulo para su matriz. Debe tener en cuenta que, de haber sido advertido :)

Ver Modelo:

[Display(Name = "Which Credit Cards are Accepted:")] 
     public string[] CreditCards { get; set; } 

Ayudante:

public static HtmlString CheckboxGroup<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> propertySelector, Type EnumType) 
     { 
      var groupName = GetPropertyName(propertySelector); 
      var modelValues = ModelMetadata.FromLambdaExpression(propertySelector, htmlHelper.ViewData).Model;//propertySelector.Compile().Invoke(htmlHelper.ViewData.Model); 
     StringBuilder literal = new StringBuilder(); 

     foreach (var value in Enum.GetValues(EnumType)) 
     { 
      var svalue = value.ToString(); 
      var builder = new TagBuilder("input"); 
      builder.GenerateId(groupName); 
      builder.Attributes.Add("type", "checkbox"); 
      builder.Attributes.Add("name", groupName); 
      builder.Attributes.Add("value", svalue); 
      var contextValues = HttpContext.Current.Request.Form.GetValues(groupName); 
      if ((contextValues != null && contextValues.Contains(svalue)) || (modelValues != null && modelValues.ToString().Contains(svalue))) 
      { 
       builder.Attributes.Add("checked", null); 
      } 

      literal.Append(String.Format("</br>{1}&nbsp;<span>{0}</span>", svalue.Replace('_', ' '),builder.ToString(TagRenderMode.Normal))); 
     } 

     return (HtmlString)htmlHelper.Raw(literal.ToString()); 
    } 

    private static string GetPropertyName<T, TProperty>(Expression<Func<T, TProperty>> propertySelector) 
    { 
     var body = propertySelector.Body.ToString(); 
     var firstIndex = body.IndexOf('.') + 1; 
     return body.Substring(firstIndex); 
    } 

HTML:

@Html.CheckboxGroup(m => m.CreditCards, typeof(VendorCertification.Enums.CreditCardTypes)) 

Uso esto si las extensiones de ayuda susto usted:

  <input id="CreditCards" name="CreditCards" type="checkbox" value="Visa" 
      @(Model.CreditCards != null && Model.CreditCards.Contains("Visa") ? "checked=true" : string.Empty)/> 
      &nbsp;<span>Visa</span><br /> 

      <input id="CreditCards" name="CreditCards" type="checkbox" value="MasterCard" 
      @(Model.CreditCards != null && Model.CreditCards.Contains("MasterCard") ? "checked=true" : string.Empty)/> 
      &nbsp;<span>MasterCard</span><br /> 
-2

Para mí esto también funciona, y creo que este es el más simple (leyendo las respuestas anteriores).

El modelo de vista tiene una cadena [] para las casillas de verificación.

public string[] Set { get; set; } 

La vista tiene este código y puede repetir la entrada tantas veces como lo necesite. name, id del control de entrada tiene que coincidir con el nombre de la propiedad del viewmodel.

<div class="col-md-3"> 
    <div class="panel panel-default panel-srcbox"> 
    <div class="panel-heading"> 
     <h3 class="panel-title">Set</h3> 
    </div> 
    <div class="panel-body"> 
     <div class="form-group-sm"> 
     <label class="control-label col-xs-3">1</label> 
     <div class="col-sm-8"> 
      <input type="checkbox" id="Set" name="Set" value="1" /> 
     </div> 
     <label class="control-label col-xs-3">2</label> 
     <div class="col-sm-8"> 
      <input type="checkbox" id="Set" name="Set" value="2" /> 
     </div> 
     </div> 
    </div> 
    </div> 
</div> 

En el método de publicación, la variable Establecer es una matriz con los valores comprobados.

Cuestiones relacionadas