【问题标题】:Showing a partial view in a modal popup在模式弹出窗口中显示部分视图
【发布时间】:2017-12-05 00:56:45
【问题描述】:

我有一个名为 Search.cshtml 的局部视图,它显示在 /Home/Index 中。在这个文件中,我有一个 HTML 表单,它使用搜索结果搜索并拉回 /Views/Accounts/Index。我想在搜索视图中的模态弹出 div 中显示这些结果。

当我在下面的代码中单击搜索(sumbit 输入)时,我得到一个空模式。

说到 MVC,我还是个新手。我尝试了一些在 Stack Overflow 上找到的不同结果,但我无法找到解决方案。下面的代码至少给了我一个模态弹出窗口,虽然它是空白的。

我错过了一些非常简单的东西吗?我已经尝试了下面模态体中的所有内容(Html.Action、RenderAction、Partial、RenderPartial),但似乎没有任何效果。还有,我是不是找错树了?

我有几个屏幕截图和下面的代码。

/Home/Index with Search partial view

Empty Search Modal

搜索.cshtml

@model CustomerRelationshipManager.Models.Search

@{ViewBag.Title = "Search";}
@using (Html.BeginForm("Index", "Accounts", new { id = "searchForm" }))
{

<div style="border: solid 1px #ccc; padding: 30px 0 30px 30px; border-radius: 5px;
    width: 325px; margin: auto; display: table;">
    <table>
        <tr>
            <td valign="top">
                Search By:
            </td>
            <td>
                @Html.DropDownList("Search_Type", "Search_Type")
            </td>
        </tr>
        <tr>
            <td valign="top"></td>
            <td>
                @Html.TextBox("Search_String")
            </td>
        </tr>
        <tr>
            <td></td>
            <td>
                <input type="submit" data-toggle="modal" data-target="#myModal" value="Search" />
            </td>
        </tr>
    </table>
</div>

<div class="modal fade" id="myModal">
    <div class="modal-dialog">
        <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">Modal title</h4>
            </div>
            <div class="modal-body">
                @{Html.Action("Index","Accounts");}
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

}

HomeController.cs

    public ActionResult Search()
    {
        List<SelectListItem> items = new List<SelectListItem>();
        items.Add(new SelectListItem() { Text = "Account Number", Value = "Account_ID" });
        items.Add(new SelectListItem() { Text = "Last Name", Value = "Last_Name" });
        items.Add(new SelectListItem() { Text = "Phone Number", Value = "Phone_Number" });
        ViewBag.Search_Type = items;
        return PartialView();
    }

    [HttpPost]
    [AllowAnonymous]
    public ActionResult Search(Search search)
    {

        return PartialView("~/Accounts/Index");
        //return RedirectToAction("Index", "Accounts");
    }

AccountController.cs(我想从这个控制器调用 Index())

public ActionResult Index(string Search_Type, string Search_String)
    {
        if (Search_String == null)
        {
            var accounts = db.Accounts
                .Include(a => a.Account_Type)
                .Include(a => a.Account_Person)
                .Include(a => a.Account_Address)
                .Include(a => a.Account_Contact);
            return PartialView(accounts.ToList());
        }
        else
        {
            if (Search_Type == "Account_ID")
            {
                var accounts = db.Accounts
                .Include(a => a.Account_Type)
                .Include(a => a.Account_Person)
                .Include(a => a.Account_Address)
                .Include(a => a.Account_Contact)
                .Where(a => a.Account_ID.ToString() == Search_String);
                return PartialView(accounts.ToList());
            }
            else if (Search_Type == "Last_Name")
            {
                var accounts = db.Accounts
                .Include(a => a.Account_Type)
                .Include(a => a.Account_Person)
                .Where(b => b.Account_Person.Any(c => c.Person.Last_Name.StartsWith(Search_String)))
                .Include(a => a.Account_Contact)
                .Include(a => a.Account_Address);
                return PartialView(accounts.ToList());
            }
            else if (Search_Type == "Phone_Number")
            {
                var accounts = db.Accounts
                .Include(a => a.Account_Type)
                .Include(a => a.Account_Person)
                .Include(a => a.Account_Contact)
                .Where(b => b.Account_Contact.Any(c => c.Contact.Value == Search_String && c.Contact.Contact_Type.Name.Contains("Phone")))
                .Include(a => a.Account_Address);
                return PartialView(accounts.ToList());
            }
            else
            {
                var accounts = db.Accounts
                    .Include(a => a.Account_Type)
                    .Include(a => a.Account_Person)
                    .Include(a => a.Account_Address)
                    .Include(a => a.Account_Contact);
                return PartialView(accounts.ToList());
            }
        }

Account Index.cshtml(我想在模式弹出窗口中显示)

@model IEnumerable<CustomerRelationshipManager.Models.Account>

@{
ViewBag.Title = "Home";
}

<h2>Index</h2>

<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
    <th>Account #</th>
    <th>Contact Name(s)</th>
    <th>Address</th>
    <th>Contact</th>
</tr>
w2
@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Account_ID)
            <span>&nbsp;</span>
        </td>
        <td>
            @foreach (var i in item.Account_Person)
            {
                <span>
                    <b>@Html.DisplayFor(x => i.Person_Type.Name)</b>
                    <br />
                    @Html.DisplayFor(x => i.Person.First_Name)
                    &nbsp;
                    @Html.DisplayFor(x => i.Person.Last_Name)
                </span>
                <br />
            }
        </td>
        <td>
            @foreach (var i in item.Account_Address)
            {
                <span>
                    <b>@Html.DisplayFor(x => i.Address_Type.Name)</b>
                    <br />
                    @Html.DisplayFor(x => i.Address.Address1)
                    <br />
                    @Html.DisplayFor(x => i.Address.Address2)
                    @if (i.Address.Address2 != null)
                    { <br />}
                    @Html.DisplayFor(x => i.Address.City)
                    &nbsp;
                    @Html.DisplayFor(x => i.Address.State)
                    &nbsp;
                    @Html.DisplayFor(x => i.Address.Postal_Code)
                    <br />
                    @Html.DisplayFor(x => i.Address.Country)
                    <br />
                </span>
            }
        </td>
        <td>
            @foreach (var i in item.Account_Contact)
            {
                <span>
                    <b>@Html.DisplayFor(x => i.Contact.Contact_Type.Name)</b>
                    <br />
                    @Html.DisplayFor(x => i.Contact.Value)
                    <br />
                </span>

            }

        </td>
        <td>
            @Html.ActionLink("Edit", "Edit", new { id = item.Account_ID }) |
            @Html.ActionLink("Details", "Details", new { id = item.Account_ID }) |
            @Html.ActionLink("Delete", "Delete", new { id = item.Account_ID })
        </td>
    </tr>
}

【问题讨论】:

  • 如果您的提交按钮在表单标签内,单击该按钮将执行表单提交。您需要对 action 方法进行 ajax 调用以获取部分视图结果并更新模态内容。

标签: c# asp.net-mvc modal-dialog partial-views


【解决方案1】:

使用您当前的代码,当用户单击提交按钮时,它将执行正常的表单提交,因为您的提交按钮位于 form 标记内。对于您的用例,您应该使用 javascript 劫持正常形式的 submit 事件并对您的操作方法进行 ajax 调用,它将使用 search_typesearch_string 参数来获取过滤后的数据并返回部分视图结果。此部分视图结果是您要在模式对话框中显示的 HTML 标记。一旦您的 ajax 调用收到来自服务器的响应,使用此响应更新模态对话框的正文内容并触发模态对话框。

@using (Html.BeginForm("Index", "Accounts", FormMethod.Post, new { id = "searchForm" }))
{
    <div>
        <input type="text" name="Search_String" />
        <input type="submit" id="submit" value="Search" />
    </div>
}    
<div class="modal fade" id="myModal">
    <div class="modal-dialog">
        <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">Modal title</h4>
            </div>
            <div class="modal-body">
            </div>
            <div class="modal-footer">
                <button type="button" class="btn" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div><!-- /.modal -->

现在有一些 javascript 代码,它们会监听搜索表单上的提交事件并停止正常行为(正常表单提交),而是执行 ajax 表单提交。

$(document).ready(function () {

    $('#searchForm').submit(function (e) {
        e.preventDefault();
        var $form = $(this);

        $.post($form.attr("action"), $form.serialize()).done(function (res) {
            $mymodal = $("#myModal");
            //update the modal's body with the response received
            $mymodal.find("div.modal-body").html(res);
            // Show the modal
            $mymodal.modal("show");
        });
    });

});

现在您必须确保您的 Index 操作方法返回一个局部视图(这样它就不会执行任何布局代码,而只是执行该视图代码)。

[HttpPost]
public ActionResult Index(string Search_Type, string Search_String)
{
    // Your existing filtering code goes here.
    return PartialView(accounts.ToList());
}

【讨论】:

  • 嗨,我添加了上面的代码,但我似乎无法让它工作。我遇到的第一个错误是 $ 未定义。发生这种情况是因为我必须将 JS 代码添加到 _layout.cshtml,因为该代码所依赖的脚本正在那里加载。现在,我回到了开始的地方,弹出一个空的模式弹出窗口。
  • 这意味着您在页面中包含之前使用 jQuery。检查页面的视图源并查看包含 jQuery 库的行和使用 $ 的行的顺序。您可能希望使用scripts 部分来包含您的页面级脚本,以确保在页面中包含 jQuery 之后执行它。参考这个where should i place the js script files in a mvc application so jquery works well?
【解决方案2】:

我想通了!

  1. 我将模态框移到 Search.cshtml 中的 HTML.BeginForm 之外。然后,我简化了表单上的输入并删除了 data-toggle 和 data-target 属性。

    @model CustomerRelationshipManager.Models.Search
    
    @{
      ViewBag.Title = "Search";
    }
    @using (Html.BeginForm("Index", "Accounts", FormMethod.Post, new { id = "searchForm" }))
    {
    
    <div style="border: solid 1px #ccc; padding: 30px 0 30px 30px; border-radius: 5px;
    width: 325px; margin: auto; display: table;">
        <table>
        <tr>
            <td valign="top">
                Search By:
            </td>
            <td>
                @Html.DropDownList("Search_Type", "Search_Type")
            </td>
        </tr>
        <tr>
            <td valign="top"></td>
            <td>
                @Html.TextBox("Search_String")
            </td>
        </tr>
        <tr>
            <td></td>
            <td>
                <input type="submit" id="submit" value="Search" />
            </td>
        </tr>
    </table>
    </div>
    }
    <div class="modal fade" id="myModal">
        <div class="modal-dialog">
        <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">Modal</h4>
            </div>
            <div class="modal-body">
    
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
    

  2. 我将 javascript 移至 _layout.cshtml 共享文件的底部。

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)
    
    <script type="text/javascript">
    $(document).ready(function () {            
        $('#searchForm').submit(function (e) {
            e.preventDefault();
            var $form = $(this);
            $.post($form.attr("action"), $form.serialize()).done(function (res) {
                $mymodal = $("#myModal");
                //update the modal's body with the response received
                $mymodal.find("div.modal-body").html(res);
                // Show the modal
                $mymodal.modal("show");
            });
        });
    
       });
    
  3. 在弄清楚这一点后,我发现了一个 LINQ 错误,这是通过在 AccountsController 的 Index() 函数中设置断点发现的。一旦我解决了这个问题,我的 AccountsController 中的 Index() 操作就会出现在我的模态弹出窗口中。

HomeController Search() Modal Dialog Displaying AccountsController Index()

感谢你的帮助,Shyju!

【讨论】:

  • 点击“保存更改”时如何调用partialView控制器和方法?
猜你喜欢
  • 1970-01-01
  • 2015-07-10
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多