11

I have a partial view in MVC that goes something like:

<div id="comments">
    ...
</div>

Inside that div there's a form that calls a controller using AJAX and gets back that same partial view. The problem is that the results of calling the view replaces the contents of the div, not the whole div, and I end up with:

<div id="comments">
    <div id="comments">
        ...
    </div>
</div>

The only solution I can think about with my week of experience in ASP.Net MVC and AJAX is to put the div outside the partial view and make the partial view only contain the inside part, but then the form would refer to an id outside the view where the form is located breaking the little encapsulation I have left there. Is there any better solution?

6 Answers 6

6

The unobtrusive Ajax library that ships with .NET MVC 3 uses callbacks that are based on the four callbacks from jQuery.ajax. However, the InsertionMode = InsertionMode.Replace from the Ajax.BeginForm method does not result in jQuery's replaceWith being called. Instead, .html(data) is used to replace the contents of the target element (and not the element itself).

I have described a solution to this problem on my blog: http://buildingwebapps.blogspot.com/2011/11/jquerys-replacewith-and-using-it-to.html

Sign up to request clarification or add additional context in comments.

1 Comment

This solution works perfectly. I must admit that is freaks me out that I'm bound to an edited version of the unobtrusive Ajax library. If I allow nuget to upgrade in the future, then my app will break. I hope that Microsoft add this functionality in the future. It's really the only solution for inline editing of line items.
3

Are you using an AjaxHelper.Form or jQuery. If you are using jQuery, have you tried using replaceWith()? Using AjaxHelper are you using AjaxOptions { InsertionMode = InsertionMode.Replace }? I would think that using either you would be able to replace the entire DIV with the results from the partial view.

1 Comment

I'm using AjaxHelper.Form and InsertionMode.Replace is the default. I haven't tried checking it because the alternatives are before and after, which are definitely not what I want. Maybe I should try with jQuery, but I first have to learn how.
3

Using

AjaxOptions { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace } 

should replace the whole content of '#myDiv' element, as tvanfosson says. Your problem is where is '#myDiv' located. Here's an example:

<div id="myDiv">
    <% Html.RenderPartial("MyPartialView"); %>
</div>

where MyPartialView is:

<div id="comments">
    <% using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace } )) {%>        
    ...
    <input type="submit" value="Submit comment" />
    <% } %>
</div>

If you include '#myDiv' div inside the partial view, it will be rendered right after receiving the response (together with its content), and then it's content will be replace with the response which is the same partial view (including its own '#myDiv' div), and that's why you always end up with 2 nested divs.

You should always use a container for your partial views and then set the UpdateTargetId to the container id.

Edit: I updated the code to represent the exact situation you describe in your question.

1 Comment

What is when the partial view needs some data? How could I send the newest data to the partial view?
2

I had this same problem in Asp.Net MVC 5.

I did not want the PartialView to have some knowledge about what div it might be contained within, so I did not accept that work around.

Then, I noticed the other answers referring to ReplaceWith and found the simple solution:

InsertionMode = InsertionMode.ReplaceWith

Now, the mvc partial view can completely replace itself with the ajax helpers without having any dependencies on names outside itself.

1 Comment

Not sure how you got this to work. I do the same thing with MVC 5 and nothing is replaced. Once I add the UpdateTargetId it works.
1

Your should try with jQuery too (from my answer on MS MVC form AJAXifying techniques):

<script type="text/javascript">
    $(document).ready(function() {
        ajaxify($('div#comments'));
    });

    function ajaxify(divWithForm) {
        var form = $('form', divWithForm);
        $(':submit', form).click(function (event) {
            event.preventDefault();
            $.post(form.attr('action'), form.serialize(),
                function(data, status) {
                    if(status == 'success') {
                        var newDivWithForm = $(data);
                        ajaxify(newDivWithForm);
                        divWithForm.after(newDivWithForm).remove();
                    }
                }
            );
        });
    }
</script>

Comments

0

Did you solved the problem? I had the same issue but I found this:

http://buildingwebapps.blogspot.ro/2011/11/jquerys-replacewith-and-using-it-to.html

I hope it helps you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.