ohanaman
ohanaman

Reputation: 35

MVC partial view to Bootstrap modal injection - solution perplexing

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 ---

Upvotes: 3

Views: 8348

Answers (2)

Shaiju T
Shaiju T

Reputation: 6609

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.

Upvotes: 3

Shaiju T
Shaiju T

Reputation: 6609

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>

Upvotes: 2

Related Questions