在MVC 5 ASP中添加项目以在客户端选择列表

时间:2015-10-05 13:09:29

标签: asp.net asp.net-mvc twitter-bootstrap asp.net-mvc-5 jquery-chosen

我试图了解更多关于MVC 5的内容,以便我自己写一个博客网站,以便在我去的时候了解更多信息。

我已经为标签设置了一个选择列表,并且希望能够从创建博客条目页面添加新标签,而不必记住在创建新帖子之前设置标签。我正在思考一个"添加标签"按钮,显示一个引导模式窗口,用户可以在其中添加新标签。

这是我的控制器动作:

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>

以下是我对模态窗口的部分视图:

@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">&times;</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>

}

是否可以在客户端添加标记,将其保存到数据库中,然后将其添加到我的标记选择列表而不刷新页面?

PS:仅供参考我使用here中选择的多项选择。

@section scripts {
    <script type="text/javascript" src="~/Scripts/chosen.jquery.min.js"></script>
    <script type="text/javascript">
        $(".chosen-select").chosen()
    </script>
}

编辑:我已使用所有代码更新了问题,该视图使视图为用户提供输入新标记名称的模态窗口。我不确定如何在不离开页面的情况下发帖,所以我猜测需要某种类型的Ajax帖子。然后如何处理从该帖子返回的数据。如何将新的持久记录添加到选择列表?

我知道标签没有传递给控制器​​方法,因为它没有绑定到任何类型的模型,而是因为我在父视图上使用视图模型,我&#39 ;我不确定如何在这里处理。

2 个答案:

答案 0 :(得分:2)

为了在视图中动态添加新的BlogTag,您需要使用ajax将新标记Name发布到保存BlogTag并返回其新内容的控制器方法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); } 您的控制器方法类似于

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.Partial("_AddBlogTag", new BlogTagVM()))生成对话框html,以便在主视图中使用<form>,这将允许您使用强类型的html帮助程序,并包括客户端验证。

另请注意,嵌套的<form>元素是无效的html,因此请确保对话框的html位于视图的主Scenario Outline: Send email validation messages Given I have the email "<email>" When I send the email Then the response status code should be "500" And I get a message from the "<variable>" variable that reads "<message>" 标记之外。

答案 1 :(得分:0)

我正在做类似的事情,我认为这可能会有所帮助。就我而言,我将值从一个列表“移动”到另一个列表(从“可用”到“已使用”),然后保存“已使用”列表的值。无论如何,在控制器中,“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);
    }

非常标准的东西。