2010-08-12 23 views
6

Tôi đang làm việc trên trang nơi người dùng cần điền một số thông tin và cuối cùng chọn một hoặc nhiều khách hàng bằng các hộp kiểm.Cách sử dụng Html.CheckBox (danh sách) với IEnumerable <T> với xác thực

Danh sách khách hàng là IEnumerable<Customer> mà tôi chuyển vào Mô hình của mình. Làm cách nào để tôi tạo danh sách các hộp kiểm bằng cách sử dụng .CheckBoxFor()?

Và cuối cùng tôi muốn có thể xác thực nếu ít nhất 1 hộp kiểm đã được chọn.

Yêu cầu là đối tượng chứa thông tin mà người dùng đã nhập.

<% foreach (var customer in Model.Request.Customers) { %> 
    <%= Html.CheckBoxFor(/* customer */) %> 
<% } %> 

Mọi người có thể chỉ cho tôi đúng hướng không? Hoặc tôi đang đi về điều này tất cả các sai?

Trả lời

3

Bạn có thể tạo lớp tiện ích mở rộng tùy chỉnh html và quá tải phương thức CheckBoxFor như dưới đây. Phương pháp đánh giá siêu dữ liệu.Model đến giá trị được chuyển vào nó (như Tiểu bang Hoa Kỳ). Bạn có thể nhận được giá trị checkbox/s từ FormCollection trong ControllerAction:

public ActionResult Edit(FormCollection formCollection) 
{ 
    // Get the value(s) 
    string checkBox = formCollection["State"]; 

    // perform validation 
    .... 
} 

Ví dụ giả định một danh sách chung KeyValuePair

<% foreach (var element in UnitedStatesDictionary()) 
{ %> 
<%= Html.CheckBoxFor(model => model.State, null, element.Key) %><%= element.Value %><br /> 
<% } %> 

HtmlExtensions.cs

using System; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Web.Mvc; 
using System.Web.Routing; 

    public static class HtmlExtensions 
    { 
     /// <summary> 
     /// Checks the box for. 
     /// </summary> 
     /// <typeparam name="TModel">The type of the model.</typeparam> 
     /// <typeparam name="TValue">The type of the value.</typeparam> 
     /// <param name="html">The HTML.</param> 
     /// <param name="expression">The expression.</param> 
     /// <returns>Checkbox</returns> 
     public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) 
     { 
      return CheckBoxFor(html, expression, new RouteDirection()); 
     } 


     /// <summary> 
     /// Checks the box for. 
     /// </summary> 
     /// <typeparam name="TModel">The type of the model.</typeparam> 
     /// <typeparam name="TValue">The type of the value.</typeparam> 
     /// <param name="html">The HTML.</param> 
     /// <param name="expression">The expression.</param> 
     /// <param name="htmlAttributes">The HTML attributes.</param> 
     /// <returns>Checkbox</returns> 
     public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes) 
     { 

      return CheckBoxFor(html, expression, htmlAttributes, ""); 
     } 

     /// <summary> 
     /// Checks the box for. 
     /// </summary> 
     /// <typeparam name="TModel">The type of the model.</typeparam> 
     /// <typeparam name="TValue">The type of the value.</typeparam> 
     /// <param name="html">The HTML.</param> 
     /// <param name="expression">The expression.</param> 
     /// <param name="htmlAttributes">The HTML attributes.</param> 
     /// <param name="checkedValue">The checked value.</param> 
     /// <returns>Checkbox</returns> 
     public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes, string checkedValue) 
     { 

      ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData); 
      string htmlFieldName = ExpressionHelper.GetExpressionText(expression); 

      TagBuilder tag = new TagBuilder("input"); 
      tag.Attributes.Add("type", "checkbox"); 
      tag.Attributes.Add("name", metadata.PropertyName); 
      if (!string.IsNullOrEmpty(checkedValue)) 
      { 
       tag.Attributes.Add("value", checkedValue); 
      } 
      else 
      { 
       tag.Attributes.Add("value", metadata.Model.ToString()); 
      } 

      if (htmlAttributes != null) 
      { 
       tag.MergeAttributes(new RouteValueDictionary(htmlAttributes)); 
      } 

      if (metadata.Model.ToString() == checkedValue) 
      { 
       tag.Attributes.Add("checked", "checked"); 
      } 
      return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing)); 
     } 
    } 

Trong khi tôi đang ở nó, đây là danh sách của tôi của Hoa Kỳ để hoàn thành mã:

/// <summary> 
/// United States dictionary. 
/// </summary> 
/// <returns>List of United States</returns> 
public static List<KeyValuePair<string, string>> UnitedStatesDictionary() 
{ 
    var arrList = new List<KeyValuePair<string, string>>(); 
    arrList.Add(new KeyValuePair<string, string>("AL", "Alabama")); 
    arrList.Add(new KeyValuePair<string, string>("AK", "Alaska")); 
    arrList.Add(new KeyValuePair<string, string>("AZ", "Arizona")); 
    arrList.Add(new KeyValuePair<string, string>("AR", "Arkansas")); 
    arrList.Add(new KeyValuePair<string, string>("CA", "California")); 
    arrList.Add(new KeyValuePair<string, string>("CO", "Colorado")); 
    arrList.Add(new KeyValuePair<string, string>("CT", "Connecticut")); 
    arrList.Add(new KeyValuePair<string, string>("DE", "Delaware")); 
    arrList.Add(new KeyValuePair<string, string>("DC", "District Of Columbia")); 
    arrList.Add(new KeyValuePair<string, string>("FL", "Florida")); 
    arrList.Add(new KeyValuePair<string, string>("GA", "Georgia")); 
    arrList.Add(new KeyValuePair<string, string>("HI", "Hawaii")); 
    arrList.Add(new KeyValuePair<string, string>("ID", "Idaho")); 
    arrList.Add(new KeyValuePair<string, string>("IL", "Illinois")); 
    arrList.Add(new KeyValuePair<string, string>("IN", "Indiana")); 
    arrList.Add(new KeyValuePair<string, string>("IA", "Iowa")); 
    arrList.Add(new KeyValuePair<string, string>("KS", "Kansas")); 
    arrList.Add(new KeyValuePair<string, string>("KY", "Kentucky")); 
    arrList.Add(new KeyValuePair<string, string>("LA", "Louisiana")); 
    arrList.Add(new KeyValuePair<string, string>("ME", "Maine")); 
    arrList.Add(new KeyValuePair<string, string>("MD", "Maryland")); 
    arrList.Add(new KeyValuePair<string, string>("MA", "Massachusetts")); 
    arrList.Add(new KeyValuePair<string, string>("MI", "Michigan")); 
    arrList.Add(new KeyValuePair<string, string>("MN", "Minnesota")); 
    arrList.Add(new KeyValuePair<string, string>("MS", "Mississippi")); 
    arrList.Add(new KeyValuePair<string, string>("MO", "Missouri")); 
    arrList.Add(new KeyValuePair<string, string>("MT", "Montana")); 
    arrList.Add(new KeyValuePair<string, string>("NE", "Nebraska")); 
    arrList.Add(new KeyValuePair<string, string>("NV", "Nevada")); 
    arrList.Add(new KeyValuePair<string, string>("NH", "New Hampshire")); 
    arrList.Add(new KeyValuePair<string, string>("NJ", "New Jersey")); 
    arrList.Add(new KeyValuePair<string, string>("NM", "New Mexico")); 
    arrList.Add(new KeyValuePair<string, string>("NY", "New York")); 
    arrList.Add(new KeyValuePair<string, string>("NC", "North Carolina")); 
    arrList.Add(new KeyValuePair<string, string>("ND", "North Dakota")); 
    arrList.Add(new KeyValuePair<string, string>("OH", "Ohio")); 
    arrList.Add(new KeyValuePair<string, string>("OK", "Oklahoma")); 
    arrList.Add(new KeyValuePair<string, string>("OR", "Oregon")); 
    arrList.Add(new KeyValuePair<string, string>("PA", "Pennsylvania")); 
    arrList.Add(new KeyValuePair<string, string>("RI", "Rhode Island")); 
    arrList.Add(new KeyValuePair<string, string>("SC", "South Carolina")); 
    arrList.Add(new KeyValuePair<string, string>("SD", "South Dakota")); 
    arrList.Add(new KeyValuePair<string, string>("TN", "Tennessee")); 
    arrList.Add(new KeyValuePair<string, string>("TX", "Texas")); 
    arrList.Add(new KeyValuePair<string, string>("UT", "Utah")); 
    arrList.Add(new KeyValuePair<string, string>("VT", "Vermont")); 
    arrList.Add(new KeyValuePair<string, string>("VA", "Virginia")); 
    arrList.Add(new KeyValuePair<string, string>("WA", "Washington")); 
    arrList.Add(new KeyValuePair<string, string>("WV", "West Virginia")); 
    arrList.Add(new KeyValuePair<string, string>("WI", "Wisconsin")); 
    arrList.Add(new KeyValuePair<string, string>("WY", "Wyoming")); 
    return arrList; 
} 
+0

+1 thực sự thích ý tưởng của việc tạo ra các phần mở rộng tùy chỉnh để giải quyết ... cũng bất kỳ vấn đề thực sự – Fabian

2

Tôi đã sử dụng một lớp trợ giúp cho điều đó. nó khá đơn giản. Với lớp helper bạn có thể sử dụng một SelectList và đặt nó trong helper, giống như bạn làm cho một dropdownfor.

trong thư mục "Helpers" tôi có Checkboxlist.cs

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

    namespace MVC2_NASTEST.Helpers { 
     public static class CheckBoxListHelper { 

      public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items) { 
       return CheckBoxList(helper, name, items, null, null); 
      } 

      public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IDictionary<string, object> checkboxHtmlAttributes) { 
       return CheckBoxList(helper, name, items, null, checkboxHtmlAttributes); 
      } 

      public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues) { 
       return CheckBoxList(helper, name, items, selectedValues, null); 
      } 

      public static string CheckBoxList(this HtmlHelper helper, string name, IDictionary<string, string> items, IEnumerable<string> selectedValues, IDictionary<string, object> checkboxHtmlAttributes) { 

       var selectListItems = from i in items 
             select new SelectListItem { 
              Text = i.Key, 
              Value = i.Value, 
              Selected = (selectedValues != null && selectedValues.Contains(i.Value)) 
             }; 

       return CheckBoxList(helper, name, selectListItems, checkboxHtmlAttributes); 
      } 

      public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items) { 
       return CheckBoxList(helper, name, items, null); 
      } 

      public static string CheckBoxList(this HtmlHelper helper, string name, IEnumerable<SelectListItem> items, IDictionary<string, object> checkboxHtmlAttributes) { 
       var output = new StringBuilder(); 

       foreach (var item in items) { 
        output.Append("<div class=\"fields\"><label>"); 
        var checkboxList = new TagBuilder("input"); 
        checkboxList.MergeAttribute("type", "checkbox"); 
        checkboxList.MergeAttribute("name", name); 
        checkboxList.MergeAttribute("value", item.Value); 

        // Check to see if it's checked 
        if (item.Selected) 
         checkboxList.MergeAttribute("checked", "checked"); 

        // Add any attributes 
        if (checkboxHtmlAttributes != null) 
         checkboxList.MergeAttributes(checkboxHtmlAttributes); 

        checkboxList.SetInnerText(item.Text); 
        output.Append(checkboxList.ToString(TagRenderMode.SelfClosing)); 
        output.Append("&nbsp; " + item.Text + "</label></div>"); 
       } 

       return output.ToString(); 
      } 
     } 
    } 

mã trong bộ điều khiển của tôi:

public static List<SelectListItem> lesgeverList() { 
     return lesgeverList(-1); 
    } 

    public static List<SelectListItem> lesgeverList(int selectedID) { 
     return lesgeverList(new int[] { selectedID }); 
    } 

    public static List<SelectListItem> lesgeverList(int[] lg) { 
     NASDataContext _db = new NASDataContext(); 
     var lesg = (from l in _db.Lesgevers 
        where l.LG_Naam != "leeg" 
        orderby l.LG_Naam, l.LG_Vnaam 
        select l).ToSelectList(m => m.LG_Naam + " " + m.LG_Vnaam, m => m.LG_ID.ToString(), m => lg.Contains(m.LG_ID)); 
     return lesg.ToList(); 
    } 

    // 
    // GET: /Projectleiders/Create 

    public ActionResult Create(int projID) { 
     ViewData["projNaam"] = getProject(projID).Proj_Kortenaam; 
     int[] keys = (from p in _db.ProjectleiderProjectens 
         where p.Proj_ID == projID 
         from l in _db.Lesgevers 
         where p.LG_ID == l.LG_ID 
         select l.LG_ID).ToArray(); 

     ViewData["projleiders"] = MvcApplication.lesgeverList(keys); 

     return toegankelijk(projID, null); 
    } 

    // 
    // POST: /Projectleiders/Create 

    [HttpPost] 
    public ActionResult Create(FormCollection collection, int projID) { 

     if (collection["lesgeverlist"] != null) { 
      string[] lgevers = collection["lesgeverlist"].Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries); 
      List<ProjectleiderProjecten> lst = new List<ProjectleiderProjecten>(); 
      foreach (string s in lgevers) { 
       ProjectleiderProjecten prl = new ProjectleiderProjecten(); 
       prl.LG_ID = int.Parse(s); 
       prl.Proj_ID = projID; 

       int count = (from m in _db.ProjectleiderProjectens 
          where m.LG_ID == prl.LG_ID && m.Proj_ID == prl.Proj_ID 
          select m).Count(); 

       if (count <= 0) { 
        //deze bestaat nog niet 
        lst.Add(prl); 
       } 
      } 
      //var test = _db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString())).ToList(); 

      _db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString()))); 

      _db.ProjectleiderProjectens.InsertAllOnSubmit(lst); 
      _db.SubmitChanges(); 

      return RedirectToAction("Index"); 
     } else { 

      ModelState.AddModelError("lesgeverlist", "Je hebt geen lesgevers geselecteerd"); 

      ViewData["projleiders"] = MvcApplication.lesgeverList(); 
      ViewData["projNaam"] = getProject(projID).Proj_Kortenaam; 
      return View(); 
     } 
    } 

tôi sử dụng phần mở rộng ToSelectList mà là một cái gì đó tất cả mọi người nên có.

public static class VSKOExtensions { 
    public static IList<SelectListItem> ToSelectList<T>(this IEnumerable<T> itemsToMap, Func<T, string> textProperty, Func<T, string> valueProperty, Predicate<T> isSelected) { 
     var result = new List<SelectListItem>(); 

     foreach (var item in itemsToMap) { 
      result.Add(new SelectListItem { 
       Value = valueProperty(item), 
       Text = textProperty(item), 
       Selected = isSelected(item) 
      }); 
     } 
     return result; 
    } 
} 

mã trong tôi tạo view (đó cũng là một cái nhìn chỉnh sửa trong cùng một thời điểm) rất đơn giản

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MVC2_NASTEST.Models.ProjectleiderProjecten>" %> 
    <%@ Import Namespace="MVC2_NASTEST.Helpers" %> 

    <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
     Create 
    </asp:Content> 

    <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

     <h2>Koppel projectleider voor 
      <%= ViewData["projNaam"].ToString() %></h2> 

     <% using (Html.BeginForm()) {%> 
      <%= Html.ValidationSummary(true) %> 

      <fieldset> 
       <legend>Fields</legend> 

       <div class="editor-label"> 
        <%= Html.Label("Lesgevers")%> 
       </div> 
       <div class="editor-field"> 
        <%= Html.CheckBoxList("Lesgeverlist", ViewData["projleiders"] as List<SelectListItem>)%> 
        <%= Html.ValidationMessage("Lesgeverlist")%> 
       </div> 

       <p> 
        <input type="submit" value="Create" /> 
       </p> 
      </fieldset> 

     <% } %> 

     <div> 
      <%= Html.ActionLink("Back to List", "Index") %> 
     </div> 

    </asp:Content> 

cách hoạt động:

tôi nhận được các giá trị từ DB của những người dùng đã chọn, lấy id của họ và đưa nó vào phương thức MvcApplication.lesgeverList (các khóa);

sau đó tôi lấy lại danh sách lựa chọn, đặt nó vào chế độ xem và những người được chọn sẽ được chọn trong chế độ xem của tôi khi tôi mở nó. sau đó khi tôi thay đổi một số hộp và lưu nó, tôi kiểm tra nếu bộ sưu tập isnt null (vì vậy một cái gì đó được chọn) sau đó tôi chia các biến tôi nhận được trở lại, đó là 'giá trị của bạn đưa vào SelectList. Tôi foreach thông qua họ, phân tích chúng thành ints, lấy người dùng từ DB với ID được phân tích cú pháp của họ. Với số tôi nhìn nếu họ tồn tại hay không trong bảng 'liên kết' được gọi là _db.ProjectleiderProjectens

khi tất cả được thêm vào, tôi xóa tất cả những người 'không được chọn' trong 1 thời gian sử dụng câu lệnh LINQ

_db.ProjectleiderProjectens.DeleteAllOnSubmit(_db.ProjectleiderProjectens.Where(p => p.Proj_ID == projID && !lgevers.Contains(p.LG_ID.ToString()))); 

mà tôi nghĩ là khá dễ đọc. xóa tất cả các đối tượng khỏi, nhận tất cả các đối tượng ID của chúng và kiểm tra xem các đối tượng nào không nằm trong chuỗi [] của số

của ID của nó. nếu bạn có thêm một số câu hỏi chỉ cần hỏi.

+0

+1 sử dụng tuyệt vời các tiện ích mở rộng với .CheckBoxList() .ToSelectList () ... psst ViewData -> xấu! : D – Fabian

+0

Vì vậy, những gì bạn sử dụng thay vì ViewData cho những thứ này? :) không phải là một fan hâm mộ lớn của nó, nhưng không biết một sollution tốt hơn. – Stefanvds

+0

Tôi sẽ chuyển thông tin đó thông qua mô hình xem – Fabian

0

Chỉ cần sử dụng jQuery xác thực ở phía máy khách và sau đó để kiểm tra lại chính mình ở phía máy chủ chỉ cần đảm bảo rằng bộ sưu tập biểu mẫu có giá trị được điền.

Không có gì sai với vòng lặp for của bạn.

+0

Tôi không có quyền truy cập vào đối tượng khách hàng đơn lẻ (từ vòng lặp) trong biểu thức labmda – Fabian

+0

Tôi không biết câu trả lời nhưng bạn chỉ có thể thực hiện " /> và chèn bất cứ điều gì bạn thích. –

3

Phương thức mở rộng Html.CheckBoxFor() được thiết kế để chỉnh sửa thuộc tính mô hình kiểu boolean. Bạn muốn sử dụng nó để chọn một số đối tượng từ bộ sưu tập IEnumerable. Nó sai.

đúng cách:

theo quan điểm

<form action="/Customer/Process"> 
<% foreach (var customer in Model.Request.Customers) 
    { %> 
     <input type="checkbox" name="selectedId" value="<%= customer.id %>" /> 
     <%= customer.name %> 
     <br/> 
<% } %> 
     <input type="submit"/> 
</form> 

trong điều khiển

public string Process(IEnumerable<Guid> selectedId) 
{ 
    if (selectedId == null) 
    { 
     ModelState.AddModelError("selectedId", "Have to select at least one customer!"); 

     return View(); 
    } 

    // do something with customers' ids 
} 
+0

Giống như sự đơn giản của phương pháp này. :) –

+0

Đơn giản và nó hoạt động. –

Các vấn đề liên quan