2011-07-14 8 views
1

私はASP.Net MVC(と剃刀)にはかなり新しく、いくつか質問があります。ASP.Net MVC 3 - CheckBoxList - いくつかの提案が必要

1)

以下のように私は、チェックボックスのリストを作成するHTMLの拡張機能を作成しました:私は私の意見でこれを使用することができたとも示すように、コントローラ内の値を取得

public static HtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<InputItemInfo> ItemInfo) 
     { 
      if (String.IsNullOrEmpty(name)) 
       throw new ArgumentException("The argument must have a value", "name"); 
      if (ItemInfo == null) 
       throw new ArgumentNullException("ItemInfo"); 
      if (ItemInfo.Count < 1) 
       throw new ArgumentException("The list must contain at least one value", "ItemInfo"); 

      StringBuilder sb = new StringBuilder(); 

      ItemInfo.Insert(0, new InputItemInfo("*", "Select All", ItemInfo.All(i => i.IsChecked))); 

      foreach (InputItemInfo info in ItemInfo) 
      { 
       TagBuilder builder = new TagBuilder("input"); 
       if (info.IsChecked) builder.MergeAttribute("checked", "checked"); 
       builder.MergeAttribute("type", "checkbox"); 
       builder.MergeAttribute("value", info.Value); 
       builder.MergeAttribute("name", name); 
       builder.InnerHtml = info.DisplayText; 
       sb.Append(builder.ToString(TagRenderMode.Normal)); 
       sb.Append("<br />"); 
      } 

      return new HtmlString(sb.ToString()); 
     } 

以下:

@model List<AppTest.Models.InputExtensionsViewModel> 

@{ 
    ViewBag.Title = "Check"; 
} 

<h2>Check</h2> 

@using (Html.BeginForm()) 
{ 
    <table border="0" style="border:0px;"> 
     <tr> 
      <td valign="top"> 
       @Html.Partial("CheckBoxList", Model[0]) 
      </td> 

     </tr> 
    </table> 

    <br /> 

    <input type="submit" value="Go" /> 
} 

<div style="font-weight:bolder"> 
    @ViewData["data"] 
</div> 

コントローラ:

モデルは次のとおりです。

public class InputExtensionsViewModel 
    { 
     public string Title { get; set; } 
     public string InputElementName { get; set; } 
     public List<InputItemInfo> InputElements { get; set; } 

     public void SetSelected(string[] items) 
     { 
      if (items == null) 
       return; 

      this.InputElements.ForEach(delegate(InputItemInfo info) 
      { 
       if (items.Contains(info.Value)) 
        info.IsChecked = true; 
      }); 
     } 
    } 

私の質問があり、私はInputExtensionsViewModelモデルにプロパティに配列項目をバインドすることができたことにより、方法はありますか?ビューモデルにfacilitiesというプロパティを追加するだけであれば、自動的にバインドされず、なぜ私が私のビューにバインドしていないので、私は理解できます。しかし、私はそれを行うことができる方法を考えているようには思えません。

このチェックボックスリストはユーザーコントロールであり、私はアクションメソッドにstring []配列が多すぎるのを避けたかっただけです。

[編集] - さて、私はこれを試してみることができました。それが以前にはうまくいかなかった理由はわかりません。

2)そして、私は選択肢をチェックし、SOにこの答えを見つけた:

CheckboxList in MVC3.0

そして、私はこれを複製することができましたが、私の質問は、私はラベルを結合しないか、ありますこのチェックボックス?私のラベルは動的でモデルの一部なので、ハードコーディングすることはできません。私はHtml.LabelForを使用しようとしていたが、うまくいかなかった。私が@ Model.Textだけであれば、それは機能しませんし、ポストバック後にはプロパティにバインドされていないので、失われてしまいます。

私はグーグルで、HTMLヘルパーを作成する提案を見つけました私は以前(私の最初の質問はそれについて)だった。

不明な点がある場合は教えてください。私は精緻化することができた。すべての入力をいただければ幸いです!

ありがとうございます!次に、あなたのテンプレートは次のようになり

public class MyViewModel 
{ 
    public int Id { get; set; } 
    public bool IsChecked { get; set; } 
    public string Text { get; set; } 
} 

答えて

2

ああ、私は解決策を見つけました!

1)私の編集で示されているように、モデルに似た名前のプロパティを追加し、[HttpPost]対応のアクションメソッドでそれを使用するとうまくいきます。私がゲッターとセッターを見逃してしまったのを最後に思い出してください。 !このため

2)、MyViewModelのエディタテンプレートで、私たちは)この(**と**、言うまでもなく、削除**を追加する必要があります。

@model AppName.Models.MyViewModel 
@Html.HiddenFor(x => x.Id)   
@Html.CheckBoxFor(x => x.IsChecked) **@Model.Text 
@Html.HiddenFor(x => x.Text)** 

EDIT:

私はこのテンプレートを変更してより多くのことを行っています。ラベルコントロールがあり、以下に示すようにjqueryを介してチェックボックスに関連付けられています。 jqueryので次に

@model EncorPlusTest.Infrastructure.InputItemInfo 

@Html.HiddenFor(model => model.Value) 
@Html.CheckBoxFor(model => model.IsChecked) <label for="">@Model.Text</label> 
@Html.HiddenFor(model => model.Text) 
<br /> 

$('input:checkbox').each(function() { 
     var lbl = $(this).next('input:hidden').next('label'); 
     var forID = $(this).attr('id'); 
     $(lbl).attr('for', forID); 
    }); 

は、他人のためにその便利を願っています!

+0

しかし、この場合、@ Model.Textの出力HTMLは

+0

これは動的テキストを表示するだけです。私は今すぐラベルステートメントを持つように即興し、次にいくつかのjqueryをチェックボックスに結びつけました。私は編集を追加します! – k25

2

パート2に答えるために、あなたは簡単のようなプロパティとして、あなたのラベルテキストを追加することができます

@model AppName.Models.MyViewModel 
@Html.HiddenFor(x => x.Id)   
@Html.CheckBoxFor(x => x.IsChecked) 
@Html.LabelFor(x => x.Text) 

への唯一の欠点を上記のラベルはチェックボックスに直接リンクされません。 CheckboxList in MVC3

再利用の可能性に応じて、最初の部分で行っていたようにいつでも独自のHtmlHelperを作成し、URL Iの提案をラップすることができます上記に貼り付けられます。

+0

ありがとうございました。私はそのリンクに似たhtmlヘルパーを持っていますし、なぜ文字列[]ファシリティに直接マップすることができますが、モデル内で同じ名前のプロパティにはマップできません。しかし、@ Html.LabelFor(x => x.Text)を試してみると、Textの値ではなく "Text"(プロパティ名)が表示されます。回避策は、HTMLヘルパーを作成することでした。だからこれを行う方法はありませんか? – k25

+0

あなたの最善の策はあなた自身をロールして、あなたがより良くコントロールできるようにすることかもしれません。私は瞬時にLabelForのオーバーロードを覚えていない(または見つける)ことができません。 –

0

この問題を解決するにはjQueryを使用しないでください。入力をラベルで囲むと、同じ動作になります。

ところで、エディタテンプレートではなく別のオプションがHTMLヘルパーです。これを見てください:

public static class HtmlHelperExtensions 
{ 


    #region CheckBoxList 

    public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> listInfo) 
    { 
     return htmlHelper.CheckBoxList(name, listInfo, ((IDictionary<string, object>)null)); 
    } 

    public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> listInfo, object htmlAttributes) 
    { 
     return htmlHelper.CheckBoxList(name, listInfo, ((IDictionary<string, object>)new RouteValueDictionary(htmlAttributes))); 
    } 

    public static MvcHtmlString CheckBoxList(this HtmlHelper htmlHelper, string name, List<SelectListItem> selectListItems, IDictionary<string, object> htmlAttributes) 
    { 
     // Verify arguments 
     if (String.IsNullOrEmpty(name)) 
      throw new ArgumentNullException("name", "Name cannot be null"); 

     if (selectListItems == null) 
      throw new ArgumentNullException("selectList", "Select list cannot be null"); 

     if (selectListItems.Count() < 1) 
      throw new ArgumentException("Select list must contain at least one value", "selectList"); 

     // Define items 
     StringBuilder items = new StringBuilder(); 

     int index = 0; 
     // Loop through items) 
     foreach (SelectListItem i in selectListItems) 
     { 
      // hidden value 
      TagBuilder hiddenValue = new TagBuilder("input"); 
      hiddenValue.MergeAttribute("type", "hidden"); 
      hiddenValue.MergeAttribute("value", i.Value); 
      hiddenValue.MergeAttribute("id", string.Format("{0}_{1}__Value", name, index)); 
      hiddenValue.MergeAttribute("name", string.Format("{0}[{1}].Value", name, index)); 
      // check box 
      TagBuilder checkbox = new TagBuilder("input"); 
      if (i.Selected) 
       checkbox.MergeAttribute("checked", "checked"); 
      checkbox.MergeAttribute("id", string.Format("{0}_{1}__Selected", name, index)); 
      checkbox.MergeAttribute("name", string.Format("{0}[{1}].Selected", name, index)); 
      checkbox.MergeAttribute("type", "checkbox"); 
      checkbox.MergeAttribute("value", "true"); 
      // wrapper label 
      TagBuilder wrapperLabel = new TagBuilder("label"); 
      wrapperLabel.InnerHtml = checkbox.ToString(TagRenderMode.SelfClosing); 
      wrapperLabel.InnerHtml += i.Text; 
      // hidden selected 
      TagBuilder hiddenSelected = new TagBuilder("input"); 
      hiddenSelected.MergeAttribute("type", "hidden"); 
      hiddenSelected.MergeAttribute("value", i.Selected.ToString().ToLower()); 
      hiddenSelected.MergeAttribute("name", string.Format("{0}[{1}].Selected", name, index)); 
      // label for checkbox 
      TagBuilder checkBoxLabel = new TagBuilder("label"); 
      checkBoxLabel.MergeAttribute("for", checkbox.Attributes["id"]); 
      checkBoxLabel.MergeAttribute("id", string.Format("{0}_{1}__Text", name, index)); 
      checkBoxLabel.MergeAttribute("name", string.Format("{0}[{1}].Text", name, index)); 
      // hidden text 
      TagBuilder hiddenText = new TagBuilder("input"); 
      hiddenText.MergeAttribute("type", "hidden"); 
      hiddenText.MergeAttribute("value", i.Text); 
      hiddenText.MergeAttribute("id", string.Format("{0}_{1}__Text", name, index)); 
      hiddenText.MergeAttribute("name", string.Format("{0}[{1}].Text", name, index)); 

      // Add item 
      items.AppendLine(hiddenValue.ToString(TagRenderMode.SelfClosing)); 
      items.AppendLine(wrapperLabel.ToString(TagRenderMode.Normal)); 
      items.Append(hiddenSelected.ToString(TagRenderMode.SelfClosing)); 
      items.AppendLine(hiddenText.ToString(TagRenderMode.SelfClosing)); 

      items.AppendLine(); 

      index++; 
     } 

     return MvcHtmlString.Create(items.ToString()); 
    } 
    public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) 
    { 
     var name = ExpressionHelper.GetExpressionText(expression); 
     var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     return CheckBoxList(htmlHelper, name, metadata.Model as List<SelectListItem>); 
    } 





    #endregion 

} 
関連する問題