CheckBoxList множественный выбор: как моделировать привязку и получить все выборы? - PullRequest
3 голосов
/ 30 июля 2010

Этот код:

Html.CheckBoxList(ViewData.TemplateInfo.HtmlFieldPrefix, myList)

Производит эту наценку:

<ul><li><input name="Header.h_dist_cd" type="checkbox" value="BD" />
        <span>BD - Dist BD Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="SS" />
        <span>SS - Dist SS Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="DS" />
        <span>DS - Dist DS Name</span></li>
    <li><input name="Header.h_dist_cd" type="checkbox" value="SW" />
        <span>SW - Dist SW Name </span></li>
</ul>

Вы можете проверить несколько вариантов выбора.Возвращаемый строковый параметр Header.h_dist_cd содержит только первое выбранное значение.Что мне нужно сделать, чтобы получить другие проверенные значения?

Параметр метода post выглядит следующим образом:

public ActionResult Edit(Header header)

Ответы [ 3 ]

4 голосов
/ 30 июля 2010

Я предполагаю, что Html.CheckBoxList - это ваше расширение, и это сгенерированная вами разметка.

На основании того, что вы показываете, нужно проверить две вещи:

  1. Связыватель модели будет искать объект с именем Header со строковым свойством h_dist_cd для привязки. Ваш метод действия выглядит так, будто Header является моделью корневого представления, а не дочерним объектом вашей модели.
  2. Я не знаю, как вы справляетесь со случаем, когда флажки сняты. Обычный трюк - визуализация скрытого поля с тем же именем.

Тоже самое, но вы хотите использовать 'label for = "..."', чтобы они могли щелкнуть текст, чтобы отметить / снять галочку и получить доступ.

Я обнаружил, что использование расширений для этой проблемы подвержено ошибкам. Возможно, вы захотите рассмотреть модель дочернего представления вместо этого. Он лучше подходит для шаблонной системы EditorFor MVC2.

Вот пример из нашей системы ...

В модель представления вставьте дочернюю модель многократного использования ...

[AtLeastOneRequired(ErrorMessage = "(required)")]
public MultiSelectModel Cofamilies { get; set; }

Вы можете инициализировать его стандартным списком SelectListItem ...

MyViewModel(...)
{
  List<SelectListItem> initialSelections = ...from controller or domain layer...;
  Cofamilies = new MultiSelectModel(initialSelections);
  ...

Дочерняя модель MultiSelectModel. Обратите внимание на переопределение сеттера в Value ...

public class MultiSelectModel : ICountable
{
  public MultiSelectModel(IEnumerable<SelectListItem> items)
  {
    Items = new List<SelectListItem>(items);
    _value = new List<string>(Items.Count);
  } 

  public int Count { get { return Items.Count(x => x.Selected); } } 
  public List<SelectListItem> Items { get; private set; }

  private void _Select()
  {
    for (int i = 0; i < Items.Count; i++)
      Items[i].Selected = Value[i] != "false";
  }

  public List<SelectListItem> SelectedItems
  {
    get { return Items.Where(x => x.Selected).ToList(); }
  } 

  private void _SetSelectedValues(IEnumerable<string> values)
  {
    foreach (var item in Items)
    {
      var tmp = item;
      item.Selected = values.Any(x => x == tmp.Value);
    }
  } 

  public List<string> SelectedValues
  {
    get { return SelectedItems.Select(x => x.Value).ToList(); }
    set { _SetSelectedValues(value); }
  } 

  public List<string> Value
  {
    get { return _value; }
    set { _value = value; _Select(); }
  }
  private List<string> _value; 
}

Теперь вы можете разместить шаблон вашего редактора в Views / Shared / MultiSelectModel.ascx ...

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<WebUI.Cofamilies.Models.Shared.MultiSelectModel>" %>

<div class="set">

<%=Html.LabelFor(model => model)%>

<ul>
  <% for (int i = 0; i < Model.Items.Count; i++)
  {
    var item = Model.Items[i];
    string name = ViewData.ModelMetadata.PropertyName + ".Value[" + i + "]";
    string id = ViewData.ModelMetadata.PropertyName + "_Value[" + i + "]";
    string selected = item.Selected ? "checked=\"checked\"" : "";
  %>
  <li>
    <input type="checkbox" name="<%= name %>" id="<%= id %>" <%= selected %> value="true" />
    <label for="<%= id %>"><%= item.Text %></label>
    <input type="hidden" name="<%= name %>" value="false" />
  </li>
  <% } %>
</ul>
<%= Html.ValidationMessageFor(model => model) %>

Два преимущества этого подхода:

  1. Вам не нужно рассматривать список элементов отдельно от значения выбора. Вы можете поместить атрибуты в одно свойство (например, AtLeastOneRequired - это пользовательский атрибут в нашей системе)

  2. Вы разделяете модель и вид (шаблон редактора). Например, у нас есть горизонтальная и вертикальная компоновка флажков. Вы также можете отобразить «множественный выбор» в виде двух списков с кнопками «назад» и «вперед», списком с множественным выбором и т. Д.

2 голосов
/ 27 октября 2011

Я думаю, что вам нужно, как собрать выбранные значения из CheckBoxList, который выбрал пользователь, и вот мое решение для этого:

1 - Загрузите Jquery.json.js и добавьте его в свой просмотр в качестве ссылки:

2- Я добавил «.cssMyClass» ко всем элементам списка чекбоксов, поэтому я выбираю значения по их классу css:

 <script type="text/javascript" >
       $(document).ready(function () {
           $("#btnSubmit").click(sendValues);
         });

     function populateValues()
     {
         var data = new Array();
         $('.myCssClas').each(function () {
             if ($(this).attr('checked')) {
                 var x = $(this).attr("value");
                 data.push(x);
             }
         }); 

         return data;
     }

     function sendValues() {
         var data = populateValues();
               $.ajax({
                   type: 'POST',
                   url: '@Url.Content("~/Home/Save")',
                   data: $.json.encode(data),
                   dataType: 'json',
                   contentType: 'application/json; charset=utf-8',
                   success: function () { alert("1"); }
               });

       } 



 </script>

3 - Как вы можете видеть, я добавил всевыбрал значения в массив, и я передал его в действие «Сохранить» контроллера «Home» с помощью ajax 4 - в Controller вы можете получить значения, добавив массив в качестве аргумента:

 [HttpPost]
        public ActionResult Save(int[] val)
        {

I 'Я искал слишком много, но, видимо, это единственное решение.Пожалуйста, дайте мне знать, если вы найдете лучшее решение для этого.

1 голос
/ 30 июля 2010

если у вас есть несколько предметов с одинаковыми именами, вы получите их значения через запятую

...