2012-10-09 14 views
15

Ich bin ziemlich neu in der ASP.net MVC Welt und ich versuche herauszufinden, wie eine Gruppe von Kontrollkästchen gerendert werden stark in ein Ansichtsmodell eingetippt. In Webforms würde ich nur die Checkbox-Kontrolle verwenden, aber ich bin ein wenig verloren mit MVC.Wie rende ich eine Gruppe von Kontrollkästchen mit MVC 4 und View-Modelle (stark typisiert)

Ich erstelle ein einfaches Kontaktformular für ein Hochzeitsplanungsunternehmen und muss die vom Benutzer ausgewählten Kontrollkästchenwerte an meinen Controller übergeben.

Die Form Checkboxen müssen wie folgt aussehen: enter image description here

Ihre Hilfe würde sehr geschätzt werden. Vielen Dank!

Hier ist, was ich bisher habe.

CONTROLLER

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

     return RedirectToAction("ContactConfirm"); 
    } 
} 

VIEW MODELL

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... 

} 

VIEW

@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

Ich bin neugierig .. Haben Sie sogar versucht, Html.Check eingeben ...? –

+1

ja, aber ich bin mir nicht sicher, wie ich sie mit meinem View-Modell verbinden würde ... – Maddhacker24

Antwort

15

Sie die Ansicht Modell bereichern könnte:

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; } 
} 

Controller:

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"); 
    } 
} 

Ausblick:

@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

Hallo Darin, ich denke ich bin in der Nähe, aber wenn ich versuche, die Checkfelder von meinem Controller zu bekommen, bekomme ich nicht die richtigen Werte. Im Durchschleifen mit: foreach (var Vendor in ContactVM.VendorAssistances). Anbieter erscheint als NBP.ViewModels.VendorAssistanceViewModel. Irgendwelche Gedanken? – Maddhacker24

+1

Nun, es ist ziemlich normal, dass Vendor als 'VendorAssistanceViewModel' erscheint. Die Eigenschaft 'VendorAssistances' ist dann als 'IList 'definiert. Sie könnten etwas tiefer gehen, um den 'Name' und die' Checked' Eigenschaften zu sehen: 'Vendor.Name' und' Vendor.Checked'. –

+1

Danke Darin, das hat den Trick gemacht. Wie dumm von mir! – Maddhacker24

1

ein String-Array in Ihrem View-Modell verwenden. Sie können dann den Helfer verwenden, den ich zusammengehackt habe. Wenn Sie den Helper und die Enumeration nicht verwenden möchten, sehen Sie sich den eigentlichen Html an. Der Binder gibt ein Zeichenfolgenarray mit nur den ausgewählten Zeichenfolgenwerten zurück. Wenn keine ausgewählt ist, wird ein Nullwert für Ihr Array zurückgegeben. Sie müssen für das Konto, Sie wurden gewarnt :)

Ansicht Modell:

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

Helper:

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)) 

verwenden, wenn Helfer Erweiterungen schrecken Sie:

  <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

Für mich funktioniert das auch, und ich denke, das ist das einfachste (Lesen der vorherigen Antworten).

Das Viewmodel hat einen String [] für die Kontrollkästchen.

public string[] Set { get; set; } 

Die Ansicht hat diesen Code, und Sie können die Eingabe so oft wiederholen, wie Sie benötigen. Name, ID des Eingabesteuerelements muss mit dem Namen der Eigenschaft des Viewmodels übereinstimmen.

<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> 

Bei der Post-Methode ist die Set-Variable ein Array mit dem/den aktivierten Wert (en).

Verwandte Themen