ASP.NET MVCフォームのチェックボックスを処理する方法
-
03-07-2019 - |
質問
注意:この質問は9歳以上です!
最良のオプションは、新しい質問を検索するか、特定のバージョンのMVCを探して以下の回答を検索することです。ここでの回答の多くは現在廃止されています。
ご使用のバージョンに適した回答が見つかった場合は、使用しているMVCのバージョンが回答に含まれていることを確認してください。
(元の質問は以下から始まります)
これは少し奇妙に思えますが、私が知る限り、これがあなたのやり方です。
オブジェクトのコレクションがあり、ユーザーが1つ以上のオブジェクトを選択できるようにします。これは、私に<!> quot;チェックボックス付きのフォーム<!> quot;私のオブジェクトには<!> quot; selected <!> quot;という概念はありません。 (これらは、wcf呼び出しをデシリアライズすることによって形成された初歩的なPOCOです)。だから、私は次のことをします:
public class SampleObject{
public Guid Id {get;set;}
public string Name {get;set;}
}
ビュー内:
<%
using (Html.BeginForm())
{
%>
<%foreach (var o in ViewData.Model) {%>
<%=Html.CheckBox(o.Id)%> <%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
そして、コントローラーでは、これはユーザーがチェックしたオブジェクトを把握するための唯一の方法です:
public ActionResult ThisLooksWeird(FormCollection result)
{
var winnars = from x in result.AllKeys
where result[x] != "false"
select x;
// yadda
}
そもそも奇妙で、次にユーザーがチェックしたアイテムについて、FormCollectionはその値を<!> quot; true false <!> quot;としてリストします。ただ真実ではなく。
明らかに、私は何かが欠けています。これは、htmlフォーム内で動作するコレクション内のオブジェクトがUpdateModel()
を使用して、またはModelBinderを介して更新されるという考えを念頭に置いて構築されていると思います。
しかし、私のオブジェクトはこのために設定されていません。これが唯一の方法であることを意味していますか?別の方法がありますか?
解決
Html.CheckBoxはおかしなことをしています-結果のページでソースを表示すると、各チェックボックスの横に<input type="hidden" />
が生成されていることがわかります。各フォーム要素に表示される値。
試してみたので、ASP.NET MVCベータ版で確実に動作します。
Html.CheckBox()を使用する代わりに、これをビューに追加します。
<% using (Html.BeginForm("ShowData", "Home")) { %>
<% foreach (var o in ViewData.Model) { %>
<input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
<%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
チェックボックスはすべてselectedObjects
と呼ばれ、各チェックボックスのvalue
は対応するオブジェクトのGUIDです。
その後、次のコントローラーアクション(またはResponse.Write()の代わりに何か有用なことを行う同様のアクション)に投稿します
public ActionResult ShowData(Guid[] selectedObjects) {
foreach (Guid guid in selectedObjects) {
Response.Write(guid.ToString());
}
Response.End();
return (new EmptyResult());
}
この例では、チェックしたボックスのGUIDを書き込むだけです。 ASP.NET MVCは、選択されたチェックボックスのGUID値をGuid[] selectedObjects
パラメーターにマップし、Request.Formコレクションの文字列をインスタンス化されたGUIDオブジェクトに解析します。これはかなり良いと思います。
他のヒント
HtmlHelperは非入力を追加して、コントローラーに未チェック状態を通知します。 したがって、正しいチェックステータスを取得するには:
bool bChecked = form[key].Contains("true");
チェックボックスと同じ名前の非表示フィールドを配置する理由を知りたい場合は、次の理由があります:
ソースコードMVCBetaSource \ MVC \ src \ MvcFutures \ Mvc \ ButtonsAndLinkExtensions.cs
からのコメントチェックボックス用に追加の
<input type="hidden".../>
をレンダリングします。 これは、 未チェックのチェックボックスは送信されません リクエスト。非表示の入力を送信する そのことを知ることができます チェックボックスがページに存在したとき リクエストが送信されました。
背後で、コントローラーアクションメソッドのパラメーターにバインドするためにこれを知る必要があると思います。その後、私が推測するトライステートブール値(nullable boolパラメーターにバインド)を使用できます。私はそれを試していませんが、それが彼らがしたことを望んでいます。
<label for="checkbox1">Checkbox 1</label>
も使用する必要があります。ユーザーは、ラベルテキストとチェックボックス自体をクリックできるためです。また、スタイル設定が簡単で、少なくともIEでは、ページのコントロールをタブで移動すると強調表示されます。
<%= Html.CheckBox("cbNewColors", true) %><label for="cbNewColors">New colors</label>
これは単に「ああ、できる」ということだけではありません。その大幅なユーザーエクスペリエンスの強化。すべてのユーザーがラベルをクリックすることを多くの意志で知っているわけではありませんが。
これらの回答のいずれも、このためにビルトインMVC機能を使用していないことに驚いています。
このここ、実際にはラベルをチェックボックスにリンクします。 EditorTemplate フォルダーを使用して、クリーンでモジュール式の方法でこれを実現しました。
次のようなEditorTemplateフォルダーに新しいファイルが作成されます。
@model SampleObject
@Html.CheckBoxFor(m => m.IsChecked)
@Html.HiddenFor(m => m.Id)
@Html.LabelFor(m => m.IsChecked, Model.Id)
実際のビューでは、これをループする必要はありません。単に1行のコードです。
@Html.EditorFor(x => ViewData.Model)
ブログ投稿詳細については。
これまで私がやってきたことです。
表示:
<input type="checkbox" name="applyChanges" />
コントローラー:
var checkBox = Request.Form["applyChanges"];
if (checkBox == "on")
{
...
}
Html。*ヘルパーメソッドは、場合によってはあまり役に立たないことがわかったので、単純な古いHTMLで実行した方が良いと思いました。これはそのうちの1つで、もう1つはラジオボタンです。
編集:これはプレビュー5にあり、明らかにバージョン間のYMMVです。
最初の値のみを読み取ることを選択しているように見えるため、これは<!> quot; true <!> quot;チェックボックスがチェックされ、<!> quot; false <!> quot;非表示の値のみが含まれる場合。これは、次のようなコードで簡単に取得できます。
model.Property = collection["ElementId"].ToLower().StartsWith("true");
@ディランビーティーグレートファインド!!!どうもありがとうございます。さらに拡張するために、この手法はモデルの表示アプローチと完全に連携します。 MVCはとてもクールで、ビューにバインドされたModelオブジェクトと同じ名前でGuidの配列をプロパティにバインドするのに十分スマートです。例:
ViewModel:
public class SampleViewModel
{
public IList<SampleObject> SampleObjectList { get; set; }
public Guid[] SelectedObjectIds { get; set; }
public class SampleObject
{
public Guid Id { get; set; }
public string Name { get; set; }
}
}
表示:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Sample View</h2>
<table>
<thead>
<tr>
<th>Checked</th>
<th>Object Name</th>
</tr>
</thead>
<% using (Html.BeginForm()) %>
<%{%>
<tbody>
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
</tbody>
</table>
<input type="submit" value="Submit" />
<%}%>
コントローラー:
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult SampleView(Guid id)
{
//Object to pass any input objects to the View Model Builder
BuilderIO viewModelBuilderInput = new BuilderIO();
//The View Model Builder is a conglomerate of repositories and methods used to Construct a View Model out of Business Objects
SampleViewModel viewModel = sampleViewModelBuilder.Build(viewModelBuilderInput);
return View("SampleView", viewModel);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SampleView(SampleViewModel viewModel)
{
// The array of Guids successfully bound to the SelectedObjectIds property of the View Model!
return View();
}
ビューモデルの哲学に精通している人なら誰でも喜ぶでしょう。これはチャンピオンのように機能します!
各チェックボックスに異なる名前を付け、その名前の一部をactionresultsパラメーターに含めることができることも指摘したいと思います。
例、
表示:
<%= Html.CheckBox("Rs232CheckBox", false, new { @id = "rs232" })%>RS-232
<%= Html.CheckBox("Rs422CheckBox", false, new { @id = "rs422" })%>RS-422
コントローラー:
public ActionResults MyAction(bool Rs232CheckBox, bool Rs422CheckBox) {
...
}
名前が同じであるため、ビューの値はアクションに渡されます。
この解決策はあなたのプロジェクトにとって理想的ではないことは知っていますが、アイデアをそこに放り出すと思いました。
<input type = "checkbox" name = "checkbox1" /> <label> Check to say hi.</label>
コントローラーから:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection fc)
{
var s = fc["checkbox1"];
if (s == "on")
{
string x = "Hi";
}
}
この問題はリリース1.0でも発生しています。 Html.Checkbox()を使用すると、元のチェックボックスと同じ名前/ IDで別の非表示フィールドが追加されます。そして、document.GetElemtentsByName()を使用してチェックボックス配列をロードしようとしていたので、物事が台無しになっている様子を推測できます。奇妙です。
収集できるものから、モデルは、checked = trueまたはfalseを推測したくありません。このようなフォームを送信する前に、jQueryでチェックボックス要素にvalue属性を設定することでこれを回避しました。
$('input[type="checkbox"]').each(function () {
$(this).attr('value', $(this).is(':checked'));
});
この方法では、チェックボックスの値を保存するためだけに隠し要素は必要ありません。
この質問はMVC3がリリースされていないときに書かれたものであることは知っていますが、この質問に来てMVC3を使用している人は、<!> quot; correct <!> quot;これを行う方法。
全体を行うと思う間
Contains("true");
素晴らしく、きれいで、すべてのMVCバージョンで動作します。問題は、文化を考慮していないことです(boolの場合に本当に重要なように)。
<!> quot; correct <!> quot;少なくともMVC3でboolの値を計算する方法は、ValueProviderを使用することです。
var value = (bool)ValueProvider.GetValue("key").ConvertTo(typeof(bool));
許可を編集するときに、クライアントのサイトの1つでこれを行います。
var allPermissionsBase = Request.Params.AllKeys.Where(x => x.Contains("permission_")).ToList();
var allPermissions = new List<KeyValuePair<int, bool>>();
foreach (var key in allPermissionsBase)
{
// Try to parse the key as int
int keyAsInt;
int.TryParse(key.Replace("permission_", ""), out keyAsInt);
// Try to get the value as bool
var value = (bool)ValueProvider.GetValue(key).ConvertTo(typeof(bool));
}
今、これの美しさは、ほぼすべての単純なタイプでこれを使用でき、文化に基づいて正しいことさえあります(お金、小数などを考えてください)。
ValueProviderは、次のようなアクションを形成するときに使用されます:
public ActionResult UpdatePermissions(bool permission_1, bool permission_2)
ただし、これらのリストを動的に作成して値を確認しようとすると、コンパイル時にIdがわからないため、それらをオンザフライで処理する必要があります。
最も簡単な方法はそうです...
名前と値を設定します。
<input type="checkbox" name="selectedProducts" value="@item.ProductId" />@item.Name
送信時にチェックボックスの値を取得し、int配列に保存します。 その後、適切なLinQ関数。それだけです。
[HttpPost]
public ActionResult Checkbox(int[] selectedObjects)
{
var selected = from x in selectedObjects
from y in db
where y.ObjectId == x
select y;
return View(selected);
}
nautic20の答えと同じ、ViewModelのstring / int / enumのコレクションプロパティと同じ名前のMVCデフォルトモデルバインディングチェックボックスリストを使用するだけです。それだけです。
しかし、1つの問題を指摘する必要があります。各チェックボックスコンポーネントには、<!> quot; Id <!> quot;を入れないでください。 MVCモデルバインディングに影響します。
次のコードはモデルのバインドに使用できます:
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
次のコードはモデルにバインドされません(ここでの違いは、各チェックボックスにidが割り当てられていることです)
<% foreach (var item in Model.SampleObjectList)
{ %>
<tr>
<td><input type="checkbox" name="SelectedObjectIds" id="[some unique key]" value="<%= item.Id%>" /></td>
<td><%= Html.Encode(item.Name)%></td>
</tr>
<% } %>
これは、Html.CheckBox(...
を使用するときにdouble値を失うためにしたことです。Replace("true,false","true").Split(',')
4つのボックスがオン、オフ、チェックなし、オンになっている true、false、false、false、true、false に true、false、false、true。 必要なものだけ
このようなものはどうですか?
bool isChecked = false;
if (Boolean.TryParse(Request.Form.GetValues(”chkHuman”)[0], out isChecked) == false)
ModelState.AddModelError(”chkHuman”, “Nice try.”);
チェックボックスHtmlHelperを使用する場合、投稿されたチェックボックスフォームデータを配列として使用することを好みます。なぜかはわからない、他の方法が機能することは知っているが、コンマで区切られた文字列を可能な限り配列として扱うことを好むと思う。
つまり、「チェック済み」または真のテストを実行すると、次のようになります。
//looking for [true],[false]
bool isChecked = form.GetValues(key).Contains("true");
偽チェックを行うことは次のようになります。
//looking for [false],[false] or [false]
bool isNotChecked = !form.GetValues(key).Contains("true");
主な違いは、配列として返されるGetValues
を使用することです。
これを$(document).ready
で行う:
$('input:hidden').each(function(el) {
var that = $(this)[0];
if(that.id.length < 1 ) {
console.log(that.id);
that.parentElement.removeChild(that);
}
});
私の解決策は:
<input type="checkbox" id="IsNew-checkbox" checked="checked" />
<input type="hidden" id="IsNew" name="IsNew" value="true" />
<script language="javascript" type="text/javascript" >
$('#IsNew-checkbox').click(function () {
if ($('#IsNew-checkbox').is(':checked')) {
$('#IsNew').val('true');
} else {
$('#IsNew').val('false');
}
});
</script>
ここでさらに見つけることができます: http://www.blog.mieten.pl/2010/12/asp-net-mvc-custom-checkbox-as-solution-of-string-was-not-recognized- as-a-valid-boolean /
ほぼ同じ問題が発生しましたが、コントローラーの戻り値が他の値でブロックされました。
シンプルなソリューションが見つかりましたが、少し荒いようです。
コントローラーでViewbag.
と入力して、Viewbag.Checkbool
ビューに切り替えて、これを試してください@Viewbag.Checkbool
これで、コントローラーから値を取得します。
私のコントローラーパラメーターは次のようになります。
public ActionResult Anzeigen(int productid = 90, bool islive = true)
そして私のチェックボックスは次のように更新されます:
<input id="isLive" type="checkbox" checked="@ViewBag.Value" ONCLICK="window.location.href = '/MixCategory/Anzeigen?isLive=' + isLive.checked.toString()" />
@mmacaulayを使用して、boolを作成しました:
// MVC Work around for checkboxes.
bool active = (Request.Form["active"] == "on");
チェックした場合 active = true
チェックされていない場合 active = false