在 MVC 5 ASP 的客户端将项目添加到 select 列表
Add items to select list on the client side in MVC 5 ASP
我正在尝试了解更多有关 MVC 5 的信息,因此我正在为自己编写一个博客网站,以便在我学习的过程中了解更多信息。
我已经为标签设置了一个 select 列表,并且希望能够从创建博客条目页面添加新标签,而不必记住在创建新 post。我正在考虑 "Add Tag" 按钮的行,该按钮显示 bootstrap 模态 window 用户可以在其中添加新标签。
这是我的控制器操作:
public ViewResult CreateBlogPost()
{
CreateEditBlogViewModel viewModel = new CreateEditBlogViewModel();
viewModel.BlogPost = new Core.BlogPost();
viewModel.BlogPost.ShortBody = "<p>Something short and sweet to describe the post</p>";
viewModel.BlogPost.Body = "<p>Enter something blog worthy here...</p>";
viewModel.Tags = new SelectList(_blogRepo.BlogTags(), "Id", "Name");
viewModel.Categories = new SelectList(_blogRepo.BlogCategories(), "Id", "Name");
return View(viewModel);
}
这是视图中的 HTML:
<div class="row">
<div class="form-group">
@Html.LabelFor(m => m.BlogPost.Tags, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.ListBoxFor(m => m.SelectedTags, Model.Tags, new { @class = "form-control chosen-select", @data_placeholder = "Start typing to see a list of tags" })
</div>
</div>
</div>
<div class="row">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#tagModal">
Add Tag
</button>
</div>
这是我对模态 window:
的部分看法
@using (Html.BeginForm("SaveTag", "Home", FormMethod.Post, new { id = "tag-form" }))
{
@Html.AntiForgeryToken()
<!-- Modal -->
<div class="modal fade" id="tagModal" tabindex="-1" role="dialog" aria-labelledby="tagModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="tagModalLabel">Enter a name for a new tag</h4>
</div>
<div class="modal-body">
<input type="text" id="Name" placeholder="Enter a new tag name" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
}
是否可以在客户端添加标签,将其保存到数据库中,然后将其添加到我的标签 select 列表中而不刷新页面?
PS:仅供参考,我正在使用来自 here.
的 Chosen multi-select
@section scripts {
<script type="text/javascript" src="~/Scripts/chosen.jquery.min.js"></script>
<script type="text/javascript">
$(".chosen-select").chosen()
</script>
}
编辑:我已经用所有使视图为用户提供模式 window 以输入新标签名称的代码更新了问题。我只是不确定如何在不离开页面的情况下 post,所以我猜需要某种 Ajax post。然后如何处理从 post 返回的数据。然后如何将新的持久记录添加到 select 列表?
我知道标签没有传递给控制器方法,因为它没有绑定到任何类型的模型,但是因为我在父视图上使用视图模型,所以我不确定我将如何处理也就是这里。
我正在做类似的事情,我认为这可能会有所帮助。在我的例子中,我是从一个列表到另一个列表的 "moving" 值(从 "available" 到 "used"),然后保存 "used" 列表的值。无论如何,在控制器中,"used" 列表显示为一个字符串数组。这是我的代码:
public ActionResult PinchHit(FormCollection form, LineupViewModel lvm, String[] UsedPlayers)
{
[Snip]
if (ModelState.IsValid && lineupResults.IsValid)
{
[Snip]
foreach (String usedID in UsedPlayers)
{
gameState.HomeUsedPlayersIDs.Add(Convert.ToInt32(usedID));
}
uow.Repository<GameState>().Update(gameState);
uow.SaveChanges();
return RedirectToAction("Index", "GameSummary");
}
[Snip]
return View(lvm2);
}
希望对您有所帮助。
根据我的评论:
这里是一个AJAX回调机制,我用来在不重新加载页面的情况下从数据库中检索数据,您可以使用它来将数据保存到数据库中。
<script type="text/javascript">
function getPositions(id, control) {
$.ajax({
url: "@Url.Action("GetPositions", "Lineup")",
data:
{
id: id
},
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred.");
},
success: function (data) {
$(control).html("");
$.each(data, function (i, item) {
$(control).append("<option value=\"" + item.Value + "\">" + item.Text + "</option>");
}
);
}
});
}
</script>
然后在控制器中:
[HttpPost]
public ActionResult GetPositions(int id)
{
Player player = uow.Repository<Player>().GetById(id);
if (player == null)
{
return (null);
}
List<SelectListItem> positionList = new SelectList(player.Positions, "ID", "ShortName").ToList();
return Json(positionList);
}
非常标准的东西。
为了在视图中动态添加新的 BlogTag
,您需要 post 使用 ajax 将新标签 Name
添加到控制器方法中,该方法保存BlogTag
和 returns 其新的 ID
值。您的控制器方法类似于
[HttpPost]
public JsonResult CreateTag(string name)
{
BlogTag tag = new BlogTag(){ Name = name };
db.BlogTags.Add(tag);
db.SaveChanges();
return Json(tag.ID);
// If the above code could result in an error/exception, catch it and return
// return Json(null);
}
然后在视图中,将对话框提交按钮处理为 post 值并更新标签列表
var url = '@Url.Action("CreateTag")';
var tagList = $('#SelectedTags');
$('#tag-form').submit(function() {
var tagName = $('#Name').val();
$.post(url, { name: tagName }, function(id) {
if (id) {
// add the new tag to the list box
tagList.append($('<option></option>').val(id).text($('#Name').val()));
// trigger the chosen update
tagList.trigger("chosen:updated");
} else {
// Oops - display an error message?
}
}).fail(function (result) {
// Oops - display an error message?
});
return false; // cancel the default submit
});
旁注:我建议您为 BlogTagVM
创建一个视图模型(包含一个 属性 用于具有验证属性的 Name
)和一个关联的部分视图(比如 _AddBlogTag.cshtml
) 生成对话框 html,这样在主视图中你可以使用 @Html.Partial("_AddBlogTag", new BlogTagVM())
这将允许你使用强类型的 html 助手,并包括客户端验证。
另请注意,嵌套的 <form>
元素无效 html,因此请确保对话框的 html 位于视图的主要 <form>
标记之外。
我正在尝试了解更多有关 MVC 5 的信息,因此我正在为自己编写一个博客网站,以便在我学习的过程中了解更多信息。
我已经为标签设置了一个 select 列表,并且希望能够从创建博客条目页面添加新标签,而不必记住在创建新 post。我正在考虑 "Add Tag" 按钮的行,该按钮显示 bootstrap 模态 window 用户可以在其中添加新标签。
这是我的控制器操作:
public ViewResult CreateBlogPost()
{
CreateEditBlogViewModel viewModel = new CreateEditBlogViewModel();
viewModel.BlogPost = new Core.BlogPost();
viewModel.BlogPost.ShortBody = "<p>Something short and sweet to describe the post</p>";
viewModel.BlogPost.Body = "<p>Enter something blog worthy here...</p>";
viewModel.Tags = new SelectList(_blogRepo.BlogTags(), "Id", "Name");
viewModel.Categories = new SelectList(_blogRepo.BlogCategories(), "Id", "Name");
return View(viewModel);
}
这是视图中的 HTML:
<div class="row">
<div class="form-group">
@Html.LabelFor(m => m.BlogPost.Tags, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.ListBoxFor(m => m.SelectedTags, Model.Tags, new { @class = "form-control chosen-select", @data_placeholder = "Start typing to see a list of tags" })
</div>
</div>
</div>
<div class="row">
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#tagModal">
Add Tag
</button>
</div>
这是我对模态 window:
的部分看法@using (Html.BeginForm("SaveTag", "Home", FormMethod.Post, new { id = "tag-form" }))
{
@Html.AntiForgeryToken()
<!-- Modal -->
<div class="modal fade" id="tagModal" tabindex="-1" role="dialog" aria-labelledby="tagModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="tagModalLabel">Enter a name for a new tag</h4>
</div>
<div class="modal-body">
<input type="text" id="Name" placeholder="Enter a new tag name" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
}
是否可以在客户端添加标签,将其保存到数据库中,然后将其添加到我的标签 select 列表中而不刷新页面?
PS:仅供参考,我正在使用来自 here.
的 Chosen multi-select@section scripts {
<script type="text/javascript" src="~/Scripts/chosen.jquery.min.js"></script>
<script type="text/javascript">
$(".chosen-select").chosen()
</script>
}
编辑:我已经用所有使视图为用户提供模式 window 以输入新标签名称的代码更新了问题。我只是不确定如何在不离开页面的情况下 post,所以我猜需要某种 Ajax post。然后如何处理从 post 返回的数据。然后如何将新的持久记录添加到 select 列表?
我知道标签没有传递给控制器方法,因为它没有绑定到任何类型的模型,但是因为我在父视图上使用视图模型,所以我不确定我将如何处理也就是这里。
我正在做类似的事情,我认为这可能会有所帮助。在我的例子中,我是从一个列表到另一个列表的 "moving" 值(从 "available" 到 "used"),然后保存 "used" 列表的值。无论如何,在控制器中,"used" 列表显示为一个字符串数组。这是我的代码:
public ActionResult PinchHit(FormCollection form, LineupViewModel lvm, String[] UsedPlayers)
{
[Snip]
if (ModelState.IsValid && lineupResults.IsValid)
{
[Snip]
foreach (String usedID in UsedPlayers)
{
gameState.HomeUsedPlayersIDs.Add(Convert.ToInt32(usedID));
}
uow.Repository<GameState>().Update(gameState);
uow.SaveChanges();
return RedirectToAction("Index", "GameSummary");
}
[Snip]
return View(lvm2);
}
希望对您有所帮助。
根据我的评论:
这里是一个AJAX回调机制,我用来在不重新加载页面的情况下从数据库中检索数据,您可以使用它来将数据保存到数据库中。
<script type="text/javascript">
function getPositions(id, control) {
$.ajax({
url: "@Url.Action("GetPositions", "Lineup")",
data:
{
id: id
},
dataType: "json",
type: "POST",
error: function () {
alert("An error occurred.");
},
success: function (data) {
$(control).html("");
$.each(data, function (i, item) {
$(control).append("<option value=\"" + item.Value + "\">" + item.Text + "</option>");
}
);
}
});
}
</script>
然后在控制器中:
[HttpPost]
public ActionResult GetPositions(int id)
{
Player player = uow.Repository<Player>().GetById(id);
if (player == null)
{
return (null);
}
List<SelectListItem> positionList = new SelectList(player.Positions, "ID", "ShortName").ToList();
return Json(positionList);
}
非常标准的东西。
为了在视图中动态添加新的 BlogTag
,您需要 post 使用 ajax 将新标签 Name
添加到控制器方法中,该方法保存BlogTag
和 returns 其新的 ID
值。您的控制器方法类似于
[HttpPost]
public JsonResult CreateTag(string name)
{
BlogTag tag = new BlogTag(){ Name = name };
db.BlogTags.Add(tag);
db.SaveChanges();
return Json(tag.ID);
// If the above code could result in an error/exception, catch it and return
// return Json(null);
}
然后在视图中,将对话框提交按钮处理为 post 值并更新标签列表
var url = '@Url.Action("CreateTag")';
var tagList = $('#SelectedTags');
$('#tag-form').submit(function() {
var tagName = $('#Name').val();
$.post(url, { name: tagName }, function(id) {
if (id) {
// add the new tag to the list box
tagList.append($('<option></option>').val(id).text($('#Name').val()));
// trigger the chosen update
tagList.trigger("chosen:updated");
} else {
// Oops - display an error message?
}
}).fail(function (result) {
// Oops - display an error message?
});
return false; // cancel the default submit
});
旁注:我建议您为 BlogTagVM
创建一个视图模型(包含一个 属性 用于具有验证属性的 Name
)和一个关联的部分视图(比如 _AddBlogTag.cshtml
) 生成对话框 html,这样在主视图中你可以使用 @Html.Partial("_AddBlogTag", new BlogTagVM())
这将允许你使用强类型的 html 助手,并包括客户端验证。
另请注意,嵌套的 <form>
元素无效 html,因此请确保对话框的 html 位于视图的主要 <form>
标记之外。