jquery - MVC 5 与来自部分 View 验证的 Bootstrap Modal 不起作用?

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

我已经断断续续地为此工作了几天,但无法完全按照我的预期工作。 我看过很多例子,但我一定是误解了一些东西。

我拥有的是一个加载了部分 View 的 Bootstrap Modal。我想做的是验证 (希望是客户端)任何错误都会在模态中的 @ValidationSummary 中显示。最大的问题 我遇到的是,当出现错误时,它基本上不会在原始模式中显示,而是加载模式 新页面中的部分 View 。验证摘要已正确填充,但没有任何样式加上它 此时不在模式中。

*注意:我目前没有使用 AJAX 来加载模式。我最终会明白的,但我不太舒服 尚未使用 AJAX,我想先让它工作,然后我可以回来并在 AJAX 中重构。

_Layout.cshtml - 我发现一个示例,说明我需要在加载 Modal 时加载 JS.unobtrusive。我假设 我这样做是正确的,但我可能会遗漏一些东西。

<div id="modal-container" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
        </div>
    </div>
</div>


@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@RenderSection("scripts", required: false)


<script type="text/javascript">

    //****  Bootstrap Modal - used with Partial Views  ***********************
    $(function () {
        // Initalize modal dialog
        // attach modal-container bootstrap attributes to links with .modal-link class.
        // when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
        $('body').on('click', '.modal-link', function (e) {
            e.preventDefault();
            $(this).attr('data-target', '#modal-container');
            $(this).attr('data-toggle', 'modal');

            //load the unobtrusive JS code
            $jQval.unobtrusive.parse($modal-container); 

            var $form = $modal-container.find("form");
            $.validator.unobtrusive.parse($form);

        });

        // Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears
        $('body').on('click', '.modal-close-btn', function () {
            $('#modal-container').modal('hide');
        });

        //clear modal cache, so that new content can be loaded
        $('#modal-container').on('hidden.bs.modal', function () {
            $(this).removeData('bs.modal');
        });

        $('#CancelModal').on('click', function () {
            return false;
        });
    });

_PasswordReset.cshtml

div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
    <h4>Reset your Password</h4>
</div>
<div class="modal-body">
    <div class="form-horizontal">
        @using (Html.BeginForm("PasswordReset", "Member", FormMethod.Post))
        {
            @Html.AntiForgeryToken()
            @Html.ValidationSummary(false, "", new { @class = "alert alert-danger" })

            <!-- BEGIN HIDDEN FIELDS AREA -->
            @Html.HiddenFor(model => model.MemberId)
            <!-- END HIDDEN FIELDS AREA -->

            <div class="form-group">
                <label class="control-label col-xs-3">Password</label>
                <div class="col-md-9">
                    @Html.TextBoxFor(c => c.Password, new { Class = "form-control", placeholder = "New Password", autofocus = "" })
                </div>
            </div>
            <div class="form-group">
                <label class="control-label col-xs-3">Confirm</label>
                <div class="col-md-9">
                    @Html.TextBoxFor(c => c.PasswordConfirm, new { Class = "form-control", placeholder = "Confirm Password" })
                </div>
            </div>
            <div class="form-group">
                <div class="col-xs-offset-3 col-xs-9">
                    <button type="submit" id="approve-btn" class="btn btn-primary">
                        Reset
                    </button>&nbsp;&nbsp;

                    <input type="button" class="btn btn-default" value="Cancel" data-dismiss="modal" />
                </div>
            </div>
        }
    </div>
</div>

Controller - 我假设如果模型无效,那么我应该传回 PartialView,因为这是我最初加载到 Modal 中的内容?

public ActionResult PasswordReset(MemberViewModel vm)
{
    MemberPasswordReset model = new MemberPasswordReset();
    model.MemberId = vm.MemberId;

    return PartialView("_PasswordReset", model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async System.Threading.Tasks.Task<ActionResult> PasswordReset(MemberPasswordReset model)
{
    if (!ModelState.IsValid)
    {
        return PartialView("_PasswordReset", model);
    }

    ApplicationDbContext context = new ApplicationDbContext();
    UserStore<ApplicationUser> userStore = new UserStore<ApplicationUser>(context);
    UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(userStore);

    String userId = User.Identity.GetUserId();
    String hashedNewPassword = UserManager.PasswordHasher.HashPassword(model.Password);

    ApplicationUser currentUser = await userStore.FindByIdAsync(userId);
    await userStore.SetPasswordHashAsync(currentUser, hashedNewPassword);
    await userStore.UpdateAsync(currentUser);

    return RedirectToAction("MyAccount");           
}

View 模型

public class MemberPasswordReset
{
    public string Password { get; set; }

    [Compare("Password", ErrorMessage = "Confirm password doesn't match.")]
    public string PasswordConfirm { get; set; }

    public int MemberId { get; set; } 
}

Bundle.config

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
            "~/Scripts/jquery-{version}.js",
            "~/Scripts/jquery.validate.js",
            "~/Scripts/jquery.validate.unobtrusive.js"));

最佳答案

您无法传回部分 View ,因为它仅返回部分 View - 而不是 View + 模式内加载的部分 View 。所以你目前所看到的是正确的。

您需要使用 AJAX 传回 JSON 响应,以便它在模式的部分 View 中进行验证。

如果模型状态无效,则返回模型状态的键值对。一个很好的起始示例如下:Example

将其发送回您的 View 后,您可以使用 jquery 将模型错误(如果有)附加到验证摘要区域。

编辑:

请求的示例 -

Controller

public class HomeController : BaseController
{
    [HttpPost]
    public ActionResult Edit(EditViewModel vm)
    {
        if(ModelState.IsValid)
        {
             //do stuff
             return Json(new
             {
                 status = "success"
                 //return values if needed
             }
        }
        return Json(new
        {
            status = "failure",
            formErrors = ModelState.Select(kvp => new { key = kvp.Key, errors = kvp.Value.Errors.Select(e => e.ErrorMessage)})});
        }
    }
}

查看

@using (Ajax.BeginForm("Edit", new AjaxOptions { OnSuccess = "onChangeSuccess"}))
{
    //Modal header, body, footer
    //Make sure your form fields actually contain their Razor validation fields
}

JQuery

function onChangeSuccess(data) {

    if (data.status === "success") {
        $("#modalcontent").modal('hide');
        $("#message-area").html(data.view);
    }
    $.each(data.formErrors, function() {
        $("[data-valmsg-for=" + this.key + "]").html(this.errors.join());
    });
}

关于jquery - MVC 5 与来自部分 View 验证的 Bootstrap Modal 不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39533599/

相关文章:

数百万行和列的 JavaScript 数据网格

jquery - 如何在 HTML 表格中隐藏垂直滚动条并显示水平滚动条

jquery - 在变量上使用 jQuery 而不是在 DOM 上?

c# - 如何解码使用 MVC 的 Url.Encode(string url) 编码的 URL

javascript - Bootstrap-select 显示两个选择菜单

jquery - 使用ajax jquery从python Bottle检索数据

css - asp.net MVC、Bootstrap 和 CSS。下拉列表问题

c# - MVC 安全 : ViewModel vs. [Bind()] 注释。两者都需要,还是其中之一就足够了?

javascript - Bootstrap 3 Collapse - 随着类的改变改变图标

jquery - Bootstrap 下拉列表项链接单击时未执行单击事件