自动 Post 复选框点击后退页
Auto Post Back Page On CheckBox Onclick
这一定很简单,但我已经研究了几天如何通过单击复选框来更改行值。我想要的是更改单击 CheckBox 的列的值,并在 CheckBox 为真时保持选中状态。否则,如果为假,它将保持未选中状态。下面是一个屏幕截图,当一行的 Public Post 列值为 'No' 时,CheckBox 将保持未选中状态。当我检查 CheckBox 时,反之亦然意味着它将保持选中状态并且值将为“Yes”。
我不确定该怎么做,看到了一些处理这种情况的问题或链接:
ASP.NET MVC submitting form on checkbox click
How can I get CheckBox to maintain checked state across postback in ASP.NET MVC?
但我想有一些更高级的想法来实现它,因为它与 ASP.NET Web Form 完全不同。如果专家分享一些想法或有助于理解的有用链接,我将不胜感激。谢谢。
顺便说一句,以下是我正在使用的class。我不确定如何处理来自控制器的回发,到目前为止,以下是使用 Ajax 完成的。但它不工作或更新:
型号:
public class Product
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Details can't be blank")]
[DataType(DataType.Text)]
public string Name{ get; set; }
public string Date_Posted { get; set; }
public string Time_Posted { get; set; }
public string Time_Edited { get; set; }
public string Date_Edited { get; set; }
public string Public { get; set; }
public double Price { get; set; }
public int User_Id { get; set; }
public bool Status { get; set; } //This is bit column that I am trying to change and not sure how to handle this from controller
public List<Product> allLists;
public IEnumerable<Product> Items;
public Pager Pager;
}
控制器 - HomeController.cs:
[HttpPost]
public ActionResult CheckValue(int id)
{
MainDbContext db = new MainDbContext();
List result = db.Product.Find(id);
if (ModelState.IsValid)
{
result.Public = "Yes";
result.Status = true;
db.Entry(result).State = EntityState.Modified;
db.SaveChanges();
}
return View(db.Lists.ToList());
}
查看 - Home/Index:
@model OurFirstWebApp.Models.Product
@{
ViewBag.Title = "Index";
var username = User.Identity.Name;
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script language="javascript">
$(function () {
$('.toggle').change(function () {
//alert("Hello");
var self = $(this);
var url = self.data('url');
var id = self.attr('id');
//var value = self.prop('checked');
$.ajax({
url: url,
data: { id: id },
type: 'POST',
success: function (response) {
alert(response);
$("#divData").load(window.location + " #divData");
}
});
});
});
<div id="divData">
<table class="table table-bordered table-condensed" id="data">
<thead>
<tr>
<th style="text-align:center;">ID</th>
<th style="text-align:center;">Products</th>
<th style="text-align:center;">Time Posted</th>
<th style="text-align:center;">Time Edited</th>
@if (@User.Identity.IsAuthenticated)
{
<th style="text-align:center;">Status</th>
<th style="text-align:center;">Edit</th>
<th style="text-align:center;">Delete</th>
<th style="text-align:center;">Public Post</th>
}
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr>
<td id="ID" style="text-align: center;">@Html.DisplayFor(modelItem => item.Id)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Name)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Time_Posted)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Time_Edited)</td>
@if (@User.Identity.IsAuthenticated)
{
<td style="text-align: center;">@Html.CheckBoxFor(modelItem => item.Status, new { id = item.Id, @class = "toggle", data_url = Url.Action("CheckValue", "Home") })</td>
<td style="text-align: center;"><a href="@Url.Action("Edit", "Auth")/@Html.DisplayFor(modelItem => item.Id)">Edit</a></td>
<td style="text-align: center;"><a href="@Url.Action("Delete", "Auth")/@Html.DisplayFor(modelItem => item.Id)">Delete</a></td>
<td id="chngData" style="text-align: center;">@Html.DisplayFor(modelItem => item.Public)</td>
}
</tr>
}
</tbody>
</table>
您的属性 bool Status
和 string Public
令人困惑,并且在数据库中有 2 个字段表示相同的东西是个坏主意。你应该有一个 属性(比如)
public bool IsPublicPost { get; set; }
单独的复选框应该足以表示值,但如果您确实想要额外的列,则在视图模型中添加一个额外的 属性(例如)
public string PublicPostDisplayText
{
get { return IsPublicPost ? "Yes" : "No"; }
}
或更好,为输出 "Yes" 或 "No".
的属性创建一个 DisplayTemplate
接下来,您无法使用 foreach
循环正确绑定到集合模型(有关详细信息,请参阅 ),您需要使用 for
循环或自定义 EditorTemplate
对于 typeof Product
for(int i = 0; i < Model.Items.Count; i++)
{
<tr>
<td>@Html.DisplayFor(m => m.Items[i].Id)</td> // see notes below
....
<td>@Html.CheckBoxFor(m => m.Items[i].IsPublicPost, new { @class = "post-checkbox", data_id = Model.Items[i].Id })</td>
// If you really want the extra column
<td class="post-text">@Html.DisplayFor(m => m.Items[i].PublicPostDisplayText)</td>
</tr>
}
那么更新数据库的脚本就是
var url = '@Url.Action("UpdatePublicPostStatus", "Home")';
$('.post-checkbox').click(function() {
var isChecked = $(this).is(':checked');
var id = $(this).data('id');
var row = $(this).closest('tr'); // only if you display the extra column
$.post(url, { id: id, isPublicPost: isChecked }, function(response) {
if (response) {
// no need to do anything, but if you display the extra column
var displayText = isChecked ? 'Yes' : 'No';
row.find('.post-text').text(displayText);
} else {
// Oops something went wrong - reset the checkbox and display error?
}
}).fail(function() {
// Oops something went wrong - reset the checkbox and display error?
});
});
最后是控制器方法
[HttpPost]
public JsonResult UpdatePublicPostStatus(int id, bool isPublicPost)
{
MainDbContext db = new MainDbContext();
var product = db.Product.Find(id);
if (product != null) // always check
{
product.IsPublicPost = isPublicPost;
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
return Json(true);
}
// If something went wrong, e.g. an exception, then return Json(null);
}
旁注。
- 重复的
id
属性无效html(不要在里面添加then
循环,除非它们是唯一的)
- 使用样式表而不是内联样式,例如
td:nth-child(1) {
text-align:center; }
- 使用
if (ModelState.IsValid)
毫无意义(而且总是 return
true
) 在你的情况下,因为你没有发布和绑定到
模型.
这一定很简单,但我已经研究了几天如何通过单击复选框来更改行值。我想要的是更改单击 CheckBox 的列的值,并在 CheckBox 为真时保持选中状态。否则,如果为假,它将保持未选中状态。下面是一个屏幕截图,当一行的 Public Post 列值为 'No' 时,CheckBox 将保持未选中状态。当我检查 CheckBox 时,反之亦然意味着它将保持选中状态并且值将为“Yes”。
我不确定该怎么做,看到了一些处理这种情况的问题或链接:
ASP.NET MVC submitting form on checkbox click
How can I get CheckBox to maintain checked state across postback in ASP.NET MVC?
但我想有一些更高级的想法来实现它,因为它与 ASP.NET Web Form 完全不同。如果专家分享一些想法或有助于理解的有用链接,我将不胜感激。谢谢。
顺便说一句,以下是我正在使用的class。我不确定如何处理来自控制器的回发,到目前为止,以下是使用 Ajax 完成的。但它不工作或更新:
型号:
public class Product
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Details can't be blank")]
[DataType(DataType.Text)]
public string Name{ get; set; }
public string Date_Posted { get; set; }
public string Time_Posted { get; set; }
public string Time_Edited { get; set; }
public string Date_Edited { get; set; }
public string Public { get; set; }
public double Price { get; set; }
public int User_Id { get; set; }
public bool Status { get; set; } //This is bit column that I am trying to change and not sure how to handle this from controller
public List<Product> allLists;
public IEnumerable<Product> Items;
public Pager Pager;
}
控制器 - HomeController.cs:
[HttpPost]
public ActionResult CheckValue(int id)
{
MainDbContext db = new MainDbContext();
List result = db.Product.Find(id);
if (ModelState.IsValid)
{
result.Public = "Yes";
result.Status = true;
db.Entry(result).State = EntityState.Modified;
db.SaveChanges();
}
return View(db.Lists.ToList());
}
查看 - Home/Index:
@model OurFirstWebApp.Models.Product
@{
ViewBag.Title = "Index";
var username = User.Identity.Name;
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script language="javascript">
$(function () {
$('.toggle').change(function () {
//alert("Hello");
var self = $(this);
var url = self.data('url');
var id = self.attr('id');
//var value = self.prop('checked');
$.ajax({
url: url,
data: { id: id },
type: 'POST',
success: function (response) {
alert(response);
$("#divData").load(window.location + " #divData");
}
});
});
});
<div id="divData">
<table class="table table-bordered table-condensed" id="data">
<thead>
<tr>
<th style="text-align:center;">ID</th>
<th style="text-align:center;">Products</th>
<th style="text-align:center;">Time Posted</th>
<th style="text-align:center;">Time Edited</th>
@if (@User.Identity.IsAuthenticated)
{
<th style="text-align:center;">Status</th>
<th style="text-align:center;">Edit</th>
<th style="text-align:center;">Delete</th>
<th style="text-align:center;">Public Post</th>
}
</tr>
</thead>
<tbody>
@foreach (var item in Model.Items)
{
<tr>
<td id="ID" style="text-align: center;">@Html.DisplayFor(modelItem => item.Id)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Name)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Time_Posted)</td>
<td style="text-align: center;">@Html.DisplayFor(modelItem => item.Time_Edited)</td>
@if (@User.Identity.IsAuthenticated)
{
<td style="text-align: center;">@Html.CheckBoxFor(modelItem => item.Status, new { id = item.Id, @class = "toggle", data_url = Url.Action("CheckValue", "Home") })</td>
<td style="text-align: center;"><a href="@Url.Action("Edit", "Auth")/@Html.DisplayFor(modelItem => item.Id)">Edit</a></td>
<td style="text-align: center;"><a href="@Url.Action("Delete", "Auth")/@Html.DisplayFor(modelItem => item.Id)">Delete</a></td>
<td id="chngData" style="text-align: center;">@Html.DisplayFor(modelItem => item.Public)</td>
}
</tr>
}
</tbody>
</table>
您的属性 bool Status
和 string Public
令人困惑,并且在数据库中有 2 个字段表示相同的东西是个坏主意。你应该有一个 属性(比如)
public bool IsPublicPost { get; set; }
单独的复选框应该足以表示值,但如果您确实想要额外的列,则在视图模型中添加一个额外的 属性(例如)
public string PublicPostDisplayText
{
get { return IsPublicPost ? "Yes" : "No"; }
}
或更好,为输出 "Yes" 或 "No".
的属性创建一个DisplayTemplate
接下来,您无法使用 foreach
循环正确绑定到集合模型(有关详细信息,请参阅 for
循环或自定义 EditorTemplate
对于 typeof Product
for(int i = 0; i < Model.Items.Count; i++)
{
<tr>
<td>@Html.DisplayFor(m => m.Items[i].Id)</td> // see notes below
....
<td>@Html.CheckBoxFor(m => m.Items[i].IsPublicPost, new { @class = "post-checkbox", data_id = Model.Items[i].Id })</td>
// If you really want the extra column
<td class="post-text">@Html.DisplayFor(m => m.Items[i].PublicPostDisplayText)</td>
</tr>
}
那么更新数据库的脚本就是
var url = '@Url.Action("UpdatePublicPostStatus", "Home")';
$('.post-checkbox').click(function() {
var isChecked = $(this).is(':checked');
var id = $(this).data('id');
var row = $(this).closest('tr'); // only if you display the extra column
$.post(url, { id: id, isPublicPost: isChecked }, function(response) {
if (response) {
// no need to do anything, but if you display the extra column
var displayText = isChecked ? 'Yes' : 'No';
row.find('.post-text').text(displayText);
} else {
// Oops something went wrong - reset the checkbox and display error?
}
}).fail(function() {
// Oops something went wrong - reset the checkbox and display error?
});
});
最后是控制器方法
[HttpPost]
public JsonResult UpdatePublicPostStatus(int id, bool isPublicPost)
{
MainDbContext db = new MainDbContext();
var product = db.Product.Find(id);
if (product != null) // always check
{
product.IsPublicPost = isPublicPost;
db.Entry(product).State = EntityState.Modified;
db.SaveChanges();
return Json(true);
}
// If something went wrong, e.g. an exception, then return Json(null);
}
旁注。
- 重复的
id
属性无效html(不要在里面添加then 循环,除非它们是唯一的) - 使用样式表而不是内联样式,例如
td:nth-child(1) { text-align:center; }
- 使用
if (ModelState.IsValid)
毫无意义(而且总是 returntrue
) 在你的情况下,因为你没有发布和绑定到 模型.