Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace div's content by partial view or update it's content depending on what json result returns on ajax complete?

Well I have simple ajax form:

This is MyPartialView

@using(Ajax.BeginForm("action", "controller", new AjaxOptions
{
    OnBegin = "beginRequest",
    OnComplete = "completeRequest",
    HttpMethod = "POST",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "div-to-replace"
}, }))
{
    <input type="text" id="my-input" /> 
    ...
}

This is parent view:

<div id="div-to-replace">
    @Html.RenderPartial("MyPartialView")
</div>

In my controller I have:

[HttpPost]
public ActionResult action(Model model)
{
   if (ModelState.IsValid)
   {
      // do staff with model
      // return partial view
      return PartialView("MyPartialView");
   }
   // else add error and return json result
   return Json(new {error = "invalid data"});
}

And my javascript on ajax complete method:

function completeRequest(data) {
    var result = $.parseJSON(data.responseText);

    if (result != 'undefined' && result != null && result.error) {
        // just display error and not replace  all content
        // attachModelError is my custom method, it just adds vlaidation-error class to inputs, etc.
        attachModelError("my-input", result.error);
        return;
    }

    // or show returned html (depending on returned model form inputs will be modified:
    // select box with different items in my case
    $('#div-to-replace').html(data.responseText);
}

But the problem is I have empty #div-to-replace if model state is invalid. If model state is ok every thing works fine. If I use different insertion mode it creates duplicates of div's content before or after div.

Summary:
I want different InsertionMode behavior depending on json result. I don't need replace data if (result != 'undefined' && result != null && result.error).

like image 806
Dmytro Avatar asked Mar 23 '23 20:03

Dmytro


1 Answers

I had to solve this problem once so very long ago. I came up with a simple solution, which today, may not be the best solution but it gets the job done.

My solution involved setting up a controller action that would render just the partial with data that it would need and have my JavaScript request it.

C#

MyController: Controller 
{
  public ActionResult GetPartialViewAction()
  {
    return PartialView("mypartialview", new partialViewModel());
  }
}

JavaScript

$.ajax({
  url: "/my/getpartialaction/"
}).done(function(data) {
  $("#partialViewDiv").html(data);
});

HTML

<div id="partialViewDiv"></div>

A better solution would be to use a MVVM/MVC JavaScript library that would allow you to leverage html templates and only have to transmit the data over your ajax solution. I recommend looking into knockout.js or backbone.js for this more accepted pattern.

like image 122
Itanex Avatar answered Apr 06 '23 03:04

Itanex