2012-10-09 6 views
15

私はASP.net MVCの世界では新しく、私はチェックボックスのグループをレンダリングする方法を見つけようとしています。ビューモデルに強く型付けされています。 webformsで私はちょうどチェックボックスリストコントロールを使用するが、私は少しMVCで失われた。MVC 4とView Models(厳密に型指定された)を使用してチェックボックスのグループをレンダリングするには

私は結婚式計画ビジネスのための簡単な連絡フォームを作成しており、ユーザーが選択したチェックボックスの値をコントローラーに渡す必要があります。

フォームのチェックボックスは、このように見える必要があります。 enter image description here

あなたの助けをいただければ幸いです。ありがとう!

これまで私がこれまで持っていたことは次のとおりです。

CONTROLLER

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

     return RedirectToAction("ContactConfirm"); 
    } 
} 

VIEW MODEL

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

私は興味があります..あなたはHtml.Check ...を入力しようとしましたか? –

+1

はい、しかし私は私のビューモデルとそれらを接続する方法はわかりません... – Maddhacker24

答えて

15

あなたはあなたのビューモデルを豊かにできます

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

コントローラ:

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

ビュー:

@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

こんにちはダーリン、私は近いと思うが、私は正しい値を取得していない私のコントローラからチェックフィールドにアクセスしようとします。私はループを使っています:foreach(ContactVM.VendorAssistancesのvar Vendor)。ベンダーはNBP.ViewModels.VendorAssistanceViewModelとして出ています。何かご意見は? – Maddhacker24

+1

さて、ベンダーが 'VendorAssistanceViewModel'として出てくるのはかなり普通です。結局 'VendorAssistances'プロパティは' IList 'として定義されます。 'Name 'と' Checked'プロパティを見るためには、 'Vendor.Name'と' Vendor.Checked'をもっと深く見ることができます。 –

+1

ダーリンに感謝しました。愚かな私! – Maddhacker24

1

ビューモデルの文字列配列を使用してください。あなたは私が一緒にハッキングしたヘルパーを使用することができます。ヘルパーと列挙型を使用したくない場合は、実際のHTMLを下に見てください。バインダーは、選択された文字列値のみを含む文字列配列を返します。どれも選択されていない場合は、配列に対してヌル値を返します。あなたはそれを考慮しなければならない、あなたは警告されている:)

ビューモデル:

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

ヘルパー:

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

使用あなた:

  <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

私にとってはこれも機能し、これは最も簡単だと思います(これまでの回答を読んでください)。

viewmodelには、チェックボックスの文字列[]があります。

public string[] Set { get; set; } 

ビューにはこのコードがあり、必要な回数だけ入力を繰り返すことができます。名前、入力コントロールのidは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> 

postメソッドでは、Set変数はチェックされた値を持つ配列です。

関連する問題