3

I followed a great little solution over at CodeProject for injecting partial views into bootstrap modals with no explicit ajax calls required...

https://www.codeproject.com/Tips/826002/Bootstrap-Modal-Dialog-Loading-Content-from-MVC-Pa

In a nutshell, the author does this (UPDATE: I have added modal-dialog, which the author doesn't do but is required):

_Layout

<div id="modal-container" class="modal fade" tabindex="-1" role="dialog">
   <div class="modal-dialog" role="document">
       <div class="modal-content"></div>
   </div>
</div>
<script>
    $('body').on('click', '.modal-link', function (e) {
        e.preventDefault();
        $(this).attr('data-target', '#modal-container');
        $(this).attr('data-toggle', 'modal');
    });
</script>

UPDATE - Here's the _Partial

<div class="modal-header">
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
</div>

... and by doing so makes any link with class="modal-link" inject its result to the modal automatically.

Seems wonderfully simple and elegant, but just one problem: The data-target he specifies is the <div id="modal-container">. Really? Why? The content should be injected into the <div class="modal-content">, shouldn't it? But nearly everyone has no problem, and no one mentions this conundrum. For me, the solution does exactly what he's told it to, it injects into <div id="modal-container">, thereby overwriting <div class="modal-content"> with my modal-body, etc. that are the contents of my partial view, so the display is messed up -- full width of the window and transparent, because it's not going into the modal-content.

Am I missing something here?


UPDATE One of Stom's answers below is correct (I've marked it). However, as I've shown in updates above, I actually already had the <div class="modal-dialog" role="document"> in the _Layout and <div class="modal-header">, body, and footer in the _Partial. Ultimately, after this issue persisted for days, I woke up today and it just started working with no changes! Seriously? Frustrating. The problem previously was that the data-toggle was causing it to actually inject into the #modal-container, not the .modal-content. But now it started to function as Stom says the documentation says, which is that even though you set the data-toggle as the #modal-container, Bootstrap should inject it into the .modal-content. Why that was not happening before but is now, I haven't the foggiest. I haven't upgraded versions overnight or anything. Ghost problem ---

2
  • Are you using latest version of bootstrap ? Commented Dec 20, 2017 at 6:30
  • Yes - 3.3.7.... Commented Dec 20, 2017 at 6:32

2 Answers 2

3

The content should be injected into the , shouldn't it?

Before version 3.1 it should be injected root element of modal i.e your modal-container But on version 3.1 it has changed. And now the bootstrap docs says it will be injected in modal-content.

modal-content with my modal-body, etc. that are the contents of my partial view, so the display is messed up , Why?

Because your partial view should contain modal-body and not modal-content. Also Adding modal-dialog inside model root element solves the syling issue.

So below setup should work for you:

Action Methods

public ActionResult Index()
{

return View();
}




public ActionResult GetPartialData()
{
    return PartialView("_ExamplePartial");
}

Index View

<!-- Button trigger modal -->
<a data-toggle="modal" href="@Url.Action("GetPartialData","Home")" data-target="#myModal">Click me</a>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">

        </div>
    </div>
</div>

_ExamplePartial View

<div class="modal-header">
    <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
        <span aria-hidden="true">&times;</span>
    </button>
</div>

<div class="modal-body">

  <h1>Remote Partial Content</h1>

</div>

<div class="modal-footer">
    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
    <button type="button" class="btn btn-primary">Save changes</button>
</div>

Note:

This option is deprecated since v3.3.0 and has been removed in v4.

Reference:

1. 2.

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

3 Comments

Because your partial view should contain modal-body and not modal-content. Also Adding modal-dialog inside model root element solves the syling issue. --- Actually, my partial view already did contain the modal-header, modal-body, and modal-footer exactly per your example. And I already had the modal-dialog div as well. Sorry I didn't show it (I was trying to only show what the author showed). Oddly, without changing anything at all, I wake up today and the issue isn't happening anymore. It works perfectly! Arghhh!! I'm marking your answer as correct, but I think you should update it.
Hi, I'm trying to implement the exact same code but the href doesn't get executed.I think that something in the template blocks it, any idea?
@JeanJimenez , If you are using URLAction then try raw url instead or paste you code in paste bin or ask a new question.
2

Below Setup should work to inject partial view content into modal body and it doesn't mess up with your default bootstrap modal style.

Action Methods

public ActionResult Index()
{

 return View();
}


public PartialViewResult GetSomeData()
{
   System.Threading.Thread.Sleep(2000); // Just to show delay to Get data

   ViewBag.Message = "Example Data from Server"; //Using ViewBag Just for example, use ViewModel Instead

   return PartialView("~/Views/Shared/_ExamplePartial.cshtml");
}

Index View

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" id="btnGetData">
    Get Modal With Partial
</button>

<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <div id="partialViewContent">

                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                <button type="button" class="btn btn-primary">Save changes</button>
            </div>
        </div>
    </div>
</div>

_ExamplePartial View

<h2>Partial View Contents</h2>


 <h3>@ViewBag.Message</h3>


<p>Some More Static Content</p>

Script:

 <script>

    $(document).ready(function () {

        $('#btnGetData').click(function () {


            var requestUrl = '@Url.Action("GetSomeData", "Home")';

            $.get(requestUrl)

            .done(function (responsedata) {

                console.log("success");

                $("#partialViewContent").html(responsedata);

                $('#myModal').modal('show')

            })
            .fail(function () {
                alert("error");
            })
            .always(function () {
                console.log("finished");
            });

        })

        });


    </script>

2 Comments

Thank you for taking the time, but I think you've missed the point of the article and my post. You've just used an ajax call and put it into the modal-body div.
Oh I see, that was a nice share. I have answered another in post , as this might help someone. But remember this has more control over the other because you can show error details to user if ajax request fails.

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.