Only update (refresh) PartialView after submit cli

2019-09-03 15:45发布

问题:

I am having trouble only updating the contents of my partial view after clicking a input type="submit" button. I wish to only refresh the partial view and fill it with the updated model (controller code), not refresh the full page. However at the moment I've only been able to view my updated model property in these situations:

  1. Refresh the full page after submit (by return View() in the controller) Image 1
  2. Display only the Partial view after submit (by return PartialView() in the controller) Image 2

It seems to me that the JQuery call isn't implemented correctly, it is triggered in debug mode. I load/render all Javascript files in the _Layout.cshtml page. Also note: I've only yet tried to enable the #btn-plus, I am aware of this. (I've added 2 screenshots at the bottom for clarification if needed)

LoadPartialCalc.js

$("btn-plus").on("click", function () {
    $.ajax({
        url: "/Home/CalculationValidation",
        type: "POST",
        success: function (result) {
            $('#dvCalculationResult').html(result);
        }
    })
});

CalculationValidation.cshtml

@using MVCPluginTest.Models
@model MVCPluginTest.Models.CalculatorModel

@{
    ViewBag.Title = "Validation master Page";
}


<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Validation</title>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    <script src="~/Scripts/jquery.validate.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
</head>
<body>
    <div id="containter">
        <h2>Validation</h2>
        @using (Html.BeginForm("#ValidationForm"))
        {
            @Html.ValidationSummary(true)
            <fieldset>
                <p>@Html.LabelFor(model => model.Number1)</p>
                <p>@Html.EditorFor(model => model.Number1) @Html.ValidationMessageFor(model => model.Number1)</p>

                <p>@Html.LabelFor(model => model.Number2)</p>
                <p>@Html.EditorFor(model => model.Number2) @Html.ValidationMessageFor(model => model.Number2)</p>

                <p><input type="submit" value="+" name="operation" id="btn-plus"/></p>
                <p><input type="submit" value="-" name="operation" id="btn-minus"/></p>
                <p><input type="submit" value="*" name="operation" id="btn-multiply"/></p>
                <p><input type="submit" value="/" name="operation" id="btn-divide"/></p>

                @Html.ValidationMessageFor(model => model.Result)

             </fieldset>
        }
    </div>
    <div id="dvCalculationResult">
        @{ Html.RenderPartial("CalculationPartial", @Model); }
    </div>  

</body>
</html>

_Layout.cshtml (Only header is of importance)

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@ViewBag.Title - My ASP.NET Application</title>
    @Styles.Render("~/Content/css")
    @Scripts.Render("~/bundles/modernizr")
    @Styles.Render("~/Content/modify-calc-input-style")
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/modify-calc-input-style")
    @Scripts.Render("~/bundles/LoadPartialCalc")
</head>

HomeController.cs

#region /Home/CalculationValidation
public ActionResult CalculationValidation()
{
    return View(new CalculatorModel());
}
[HttpPost]
public ActionResult CalculationValidation(CalculatorModel valModel, string operation)
{
    var num1 = valModel.Number1;
    var num2 = valModel.Number2;
    if (operation == null)
    {
        ModelState.AddModelError("Operation", "No operation type selected");
        return View();
    }
    else
    {
        if (ModelState.IsValid)
        {
            switch (operation)
            {
                case "+":
                    valModel.Result = num1 + num2;
                    break;
                case "-":
                    if (ValidateNumbers(num1, num2, "-"))
                    {
                        valModel.Result = num1 - num2;
                    }
                    else
                    {
                        valModel.Result = 0;
                        ModelState.AddModelError("Result", "Minus can't be lower than 0");
                    }
                    break;
                case "*":
                    valModel.Result = num1 * num2;
                    break;
                case "/":
                    if (ValidateNumbers(num1, num2, "/"))
                    {
                        valModel.Result = num1 / num2;
                    }
                    else
                    {
                        valModel.Result = 0;
                        ModelState.AddModelError("Result", "Division not whole.");
                    }
                    break;
                default:
                    valModel.Result = 0;
                    break;
            }
        }
    }
    return PartialView("CalculationPartial", valModel);
}
#endregion

CaclculationPartial.cshtml

@using MVCPluginTest.Models
@model MVCPluginTest.Models.CalculatorModel

<h2>Result</h2>
<p id="result">@Model.Result</p>

CalculatorModel

public class CalculatorModel
{
    [Required(ErrorMessage = "Please enter a number.")]
    [Display(Name = "Number 1")]
    [RegularExpression(@"^[0-9]*$", ErrorMessage = "You can only enter numbers above 0.")]
    public double Number1
    {
        get;
        set;
    }
    [Required(ErrorMessage = "Please enter a number.")]
    [Display(Name = "Number 2")]
    [RegularExpression(@"^[0-9]*$", ErrorMessage = "You can only enter numbers above 0.")]
    public double Number2
    {
        get;
        set;
    }
    public string OperationType
    {
        get;
        set;
    }
    public double Result
    {
        get;
        set;
    }
}

Partial view before submit click

Partial view after submit click (main content gone)

Thanks in advance for any help!

Update after Sandip Patel's initial anwser: After clicking on the submit button (#btn-plus) the redirection occurs with a parameter of "Length = 15" (URL becomes: Home/CalculationValidation?Length=15). Only the partialView loads on a different page (no main content). I assume it has something to do with the way I Begin the Form.

@using (Html.BeginForm("#ValidationForm"))

As when I begin the form with

@using (Html.BeginForm("CalculationValidation", "Home", FormMethod.Post))

the page does the calculations but it reloads fully (Main content and PartialView). I'm not sure if the alteration to the URL is causing my PartialView to not update correctly, then I'm also not sure WHY it alters the URL in the first place.

回答1:

Set event.preventDefault() on form submit, it will restrict the page to refresh.

$("#ValidationForm").serialize() will serialize your data and that pass to your action.

$("#ValidationForm").submit(function (event) {
event.preventDefault();       

$.ajax({
    url: '@Url.Action("CalculationValidation", "Home")',
    dataType: 'json',
    data: $("#ValidationForm").serialize(),
    type: 'POST',
    success: function (result) {
        $("#dvCalculationResult").html(result);
    },
    error: function (xhr) {
    }
});
});