当页面有多个表单时,在回发后恢复活动引导选项卡

时间:2017-02-03 22:29:00

标签: asp.net-mvc-5 html-form bootstrap-tabs multiple-forms

我有一个ASP.Net MVC 5项目,该项目有一个包含2个引导选项卡的页面。每个选项卡有两种形式,页面上总共有4种形式。我的viewmodel有4个表单中所有字段的超集。

当我发布表单时,我希望响应视图显示发布表单时显示的相同选项卡。这个SO答案Remain bootstrap tab after postback c#表示我应该在隐藏字段中设置活动选项卡,在视图模型中返回它,然后在回发时恢复它。

这个SO答案asp.net MVC 4 multiple post via different forms表示返回的字段必须在我正在返回的表单中。这提出了一个问题,因为隐藏字段需要在所有表单的范围内。

在回发时,当我在页面上有多个表单时,如何显示在发布表单时显示的相同选项卡?

1 个答案:

答案 0 :(得分:0)

我解决了这个问题,删除了4个表单,并用一个跨越前一个表单的表单替换它。要使表单回发到正确的控制器/操作,我写了一些javascript,当其中一个调用时4个提交按钮被激活。

它将新表单的操作设置为适当的控制器/操作,然后提交表单。这样,只有一个表单和一个隐藏字段来保存活动选项卡,并且仍然可以在回发时调用正确的操作。这里有一个带有2个选项卡和(为简单起见)只有2个操作的测试程序:

查看:

    @model MultiPostDestinations.Models.HomeVM
@{
    ViewBag.Title = "Home Page";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<br/><br /><br /><br />
<div class="row">
    <div class="col-md-4">
        @using (Html.BeginForm("SubmitForm", "Home", FormMethod.Post, new { id = "submitForm", enctype = "multipart/form-data" })) {
            @Html.HiddenFor(m => m.ActiveTab)
            <div id="Tabs" role="tabpanel" class="container" style="width: 1000px">
                <!-- Nav tabs -->
                <ul class="nav nav-tabs" role="tablist">
                    <li class="active"><a href="#details" aria-controls="details" role="tab" data-toggle="tab">Details</a></li>
                    <li><a href="#history" aria-controls="history" role="tab" data-toggle="tab">Historic Model Analysis</a></li>
                </ul>
                <!-- Tab panes -->
                <div class="tab-content">
                    <div id="details" role="tabpanel" class="tab-pane fade in active">
                        <h2>Details Tab</h2>
                        <h4>label: @Model.F1</h4><br /><br />
                        @Html.DisplayFor(m => m.F1)<br /><br />
                        @Html.EditorFor(m => m.F1)<br /><br />
                        @Html.ActionLink("ActionLink Submit form", "SubmitGet", "Home", new { @class = "btn btn-default" })<br /><br />
                        <input type="submit" value="input SubmitForm" class="btn btn-default" /><br /><br />
                        <input id="submitButton1" type="button" value="javascript input to /Home/Submit1" class="btn btn-default" /><br /><br />
                    </div>
                    <div id="history" role="tabpanel" class="tab-pane fade">
                        <h2>Historic Model Analysis tab</h2>
                        <h4>label: @Model.F2</h4><br /><br />
                        @Html.DisplayFor(m => m.F2)<br /><br />
                        @Html.EditorFor(m => m.F2)<br /><br />
                        <input type="submit" value="input SubmitForm" class="btn btn-default" /><br /><br />
                        <input id="submitButton2" type="button" value="javascript input to /Home/Submit2" class="btn btn-default" /><br /><br />
                    </div>
                </div>
            </div>
        }

    </div>
</div>

@section scripts {
    <script type="text/javascript">
        $(document).ready(function () {
            $('#submitButton1').click(function (e) {
                e.preventDefault(); // recommended in SO, does not appear to be required
                $('#submitForm').attr('action', '/Home/Submit1');
                $('#submitForm').submit();
            });
            $('#submitButton2').click(function (e) {
                e.preventDefault();     // recommended in SO, does not appear to be required
                $('#submitForm').attr('action', '/Home/Submit2');
                $('#submitForm').submit();  // previous doesn't work - why?
            });

            var lastActiveTab = ($('#ActiveTab').val() !== '') ? $('#ActiveTab').val() : 'details';
            $('#Tabs a[href="#' + lastActiveTab + '"]').tab('show');
            $("#Tabs a").click(function () {
                $('#ActiveTab').val($(this).attr("href").replace("#", ""));
            });

        });
    </script>
}

这是带有2个动作的Controller:

using MultiPostDestinations.Models;
using System.Web.Mvc;

namespace MultiPostDestinations.Controllers {
    public class HomeController : Controller {
        public ActionResult Index() {
            var vm = new HomeVM() { F1 = "Index-F1", F2 = "Index-F2", ActiveTab = "" };
            return View("Index", vm);
        }

        [HttpPost]
        public ActionResult Submit1(HomeVM vm) {
            System.Diagnostics.Debug.WriteLine("HomeVM.Submit1: F1={0}, F2={1}", vm.F1 ?? string.Empty, vm.F2 ?? string.Empty);
            // ModelState.Clear();         // uncomment if you want Html.EditorFor() fields to update on postback
            return View("Index", vm);
        }

        [HttpPost]
        public ActionResult Submit2(HomeVM vm) {
            System.Diagnostics.Debug.WriteLine("HomeVM.Submit2: F1={0}, F2={1}", vm.F1 ?? string.Empty, vm.F2 ?? string.Empty);
            //ModelState.Clear();         // uncomment if you want Html.EditorFor() fields to update on postback
            return View("Index", vm);
        }

    }
}

最后是视图模型:

    namespace MultiPostDestinations.Models {
    public class HomeVM {
        public string ActiveTab { get; set; }
        public string F1 { get; set; }
        public string F2 { get; set; }

    }
}