Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly use Partial views with Ajax Begin form

I have the following code, in my index.cshtml

@using Kendo.Mvc.UI;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using xx.Relacionamiento.Modelo.Bussiness.Entities.Custom;

<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

@model PresupuestosGenerale

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";

    }

<div class="">

    <div id="ContenedorPresupuestoGeneral">
        @Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
    </div>
    <br />
    <br />

Then I have the following PartialView

@using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using Kendo.Mvc.UI;


@model PresupuestosGenerale
<div class="panel panel-default">
    <div class="panel-heading">
        @using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "ContenedorPresupuestoGeneral", InsertionMode = InsertionMode.Replace }))
        {
            @Html.HiddenFor(h => h.PresupuestoGeneralId)
            @Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
            <div class="row">
                <div class="col-lg-6 col-md-6 col-sm-6 col-xs-6">
                    <label>Presupuesto Global xx</label>
                    <br />
                    @(Html.Kendo().NumericTextBoxFor(e => e.PresupuestoGlobal)
                    .Decimals(0)
                    .DecreaseButtonTitle("Decrementar")
                    .IncreaseButtonTitle("Incrementar")
                    .Format("c0")
                    .HtmlAttributes(new { style = "width:99%;" })
                    .Max(1000000000000000000)
                    .Min(1)
                    .Step(100000)
                    .Placeholder("Presupuesto General xx"))
                    @Html.ValidationMessageFor(v => v.Valor, "", new { @style = "color: rgba(247, 20, 10, 0.97);" })
                </div>
                <div class="col-md-3">
                    <br />
                    <input type="submit" class="form-control btn btn-primary" value="Guardar Presupuesto" onclick="SetMostrarVentana();" />
                </div>
            </div>
        }


    </div>
</div>
<script type="text/javascript">

    $(function () {
        MostrarVentanaLoading = false;
        @if (!string.IsNullOrEmpty(ViewBag.MensajeError))
        {
            @:mostrarMensajeAlertGlobal("@ViewBag.MensajeError",15000)
        }
        else if (!string.IsNullOrEmpty(ViewBag.MensajeSuccess))
        {
            @:mostrarMensajeAlertSuccessGlobal("@ViewBag.MensajeSuccess", 15000);
        }
    });

</script>

Then on my controller I have business logic that returns something different depending on conditions

 public ActionResult CreateOrEditPresupuestoGeneralxx(PresupuestosGenerale presupuestoGeneralxx)
        {
            try
            {
                ModelState.Remove("PresupuestoGlobal");

                if (presupuestoGeneralxx == null)
                {
                    return PartialView();
                }
                if (!ModelState.IsValid)
                {
                    return PartialView(presupuestoGeneraxx);
                }

                if (presupuestoGeneralxx.Valor < 1)
                {
                    ModelState.AddModelError("Valor", "Por favor ingrese un presupuesto total");
                    return PartialView(presupuestoGeneralxx);
                }

So, when the user submits the form, the container from the index view is replaced with the new html.

The code works perfectly fine, however I feel that the code is ugly, not maintainable and difficult to read.

My questions, is, with asp.net mvc and ajax is there a better and more organized way to achieve the same thing with more readable code?

like image 335
Luis Valencia Avatar asked Jan 25 '16 22:01

Luis Valencia


People also ask

How do you call a partial view in Ajax success?

We see that the output has come in the success callback of the ajax() function. Want to make it simpler? Ok, let's use the load() function of jQuery and I hope this is the perfect and best way to load a partial view, using ajax(). We have replaced the ajax() function with the loadfunction.

How do you use partial views?

To create a partial view, right-click on view -> shared folder and select Add -> View option. In this way we can add a partial view. It is not mandatory to create a partial view in a shared folder but a partial view is mostly used as a reusable component, it is a good practice to put it in the "shared" folder.

How can I return partial call from Ajax?

In order to add Partial View, you will need to Right Click inside the Controller class and click on the Add View option in order to create a View for the Controller.

How load partial views in ASP NET MVC using jQuery Ajax?

You'll need to create an Action on your Controller that returns the rendered result of the "UserDetails" partial view or control. Then just use an Http Get or Post from jQuery to call the Action to get the rendered html to be displayed.


2 Answers

I would refactor the views moving the ajax form outside the partial. That way the full partial which is rendered inside the form is refreshed on ajax posts, keeps unaware and decoupled of container structure and every view has their own responsibility:

Index.cshtml

<div class="panel panel-default">
    <div class="panel-heading">
        @using (Ajax.BeginForm("CreateOrEditPresupuestoGeneralxx", new AjaxOptions() { HttpMethod = "Post", UpdateTargetId = "form-content", InsertionMode = InsertionMode.Replace }))
        {
            <div id="form-content">
                @Html.Partial("CreateOrEditPresupuestoGeneralxx", Model)
            </div>
        }
    </div>
</div>

CreateOrEditPresupuestoGeneralxx.cshtml

@using xx.Relacionamiento.Modelo.Bussiness.Entities.Enumeraciones;
@using xx.Relacionamiento.Modelo.Bussiness.Entities;
@using Kendo.Mvc.UI;

@model PresupuestosGenerale

@Html.HiddenFor(h => h.PresupuestoGeneralId)
@Html.Hidden("Categoria",CategoriaEvento.xx.ToString())
<div class="row">
...
like image 128
tede24 Avatar answered Oct 17 '22 22:10

tede24


Here is one of the example that I used in some of my projects. In this example not only PartialView is rendered, also a DropdownList value is passed to the PartialView and displayed on it.

View :

<div id="divPartialView">
    @Html.Partial("~/Views/MyPartialView.cshtml", Model)
</div>


$(document).ready(function () { 
    $(".SelectedCustomer").change(function (event) {
        $.ajax({
            url: '@Url.Action("GetPartialDiv", "Home")',
            data: { id: $(this).val() /*add other additional parameters */ },
            cache: false,
            type: "POST",
            dataType: "html",
            success: function (data, textStatus, XMLHttpRequest) {
                SetData(data);
            },
            error: function (data) { onError(data); }
        });
    });

    function SetData(data) {
        $("#divPartialView").html(data); //HTML DOM replace
    } 
});


Controller :

[HttpPost]
public PartialViewResult GetPartialDiv(int id /* ddl's selectedvalue */)
{
    Models.GuestResponse guestResponse = new Models.GuestResponse();
    guestResponse.Name = "this was generated from this ddl id:"; 
    return PartialView("MyPartialView", guestResponse);
}

Hope this helps...

like image 37
Murat Yıldız Avatar answered Oct 18 '22 00:10

Murat Yıldız