Skanda
Skanda

Reputation: 131

Unable to open Bootstrap modal popup from a partial view

I have a webgrid with a hyperlink column and upon clicking that link it should open a modal popup I have a modal named #examplemodal in a partial view named"GetDetails". Below I try to open the modal from a controller action method that returns partial view.

 @Html.ActionLink("OrderNumber","GetDetails","Home",
                  new{id = item.ID}, new{data_target="#exampleModal", data_toggle="modal", @class="modal-backdrop"});

When I click on the link with Ordernumber screen blacks out and I dont see the grid at all. Any pointers on where I am doing a mistake. I am using asp.Net mvc5 and bootstrap v4.3.1

Upvotes: 0

Views: 742

Answers (1)

David Liang
David Liang

Reputation: 21546

I think your concept is totally wrong. I assume you want to display the order details in a modal? And since you have a method to return a partial view for that already, you want to load that order details content into modal whenever the user clicks the hyperlink column?

If that's the case, bootstrap modal is not the right tool for you. It's designed to load static content. If you want to load dynamic content, i.e., order details for different order numbers, you should look into a concept called iframe, and libraries like Fancybox, etc.

Here's what I would do:

1.Define a modal layout

Because you want to display the partial view on a modal, you generally don't want to have things like sidebar, top navigation, etc, from your site layout. Hence I will define a layout for modals.

<!-- _PopupLayout.cshtml -->

<!DOCTYPE html>
<html>
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no" />

        <!-- All your necessary styles, meta data, etc -->

        <title>...</title>

        @RenderSection("css", required: false)
    </head>
    <body>
        <main class="container-fluid">
            @RenderBody()
        </main>

        <!-- All your necessary javascripts -->

        @RenderSection("scripts", required: false)
    </body>
</html>

2.Return views that use _PopupLayout

I know you've created partial views. But regular view is fine. In fact, it's better because you can setup the layout the regular view uses, as well as the view models for that.

Because you want this view to look like a bootstrap modal, you should construct your view using bootstrap modal structure.

@model ...
@{
    ViewData["Title"] = "Order Details";
    Layout = "~/Views/Shared/_PopupLayout.cshtml";
}

<div class="modal-header">
    <h5 class="modal-title">Order Details</h5>
</div>
<div class="modal-body">
    ...
</div>

3.Write JavaScript to trigger FancyBox on link clicking

You can use a custom css class for the selector for all links you want to load the iframe from. In my case I call it .popup-fancy. You can also define multiple classes for popping up different sizes of modals/fancybox modals.

$(function() {
    $().fancybox({
        selector: 'a.popup-fancy',
        defaultType: 'iframe',
        baseClass: 'fancybox-md',
        iframe: {
            preload: false
        },
        arrows: false,
        infobar: false,
        smallBtn: true
    });

    $().fancybox({
        selector: 'a.popup-fancy-lg',
        defaultType: 'iframe',
        baseClass: 'fancybox-lg',
        iframe: {
            preload: false
        },
        arrows: false,
        infobar: false,
        smallBtn: true
    });

    $().fancybox({
        selector: 'a.popup-fancy-xl',
        defaultType: 'iframe',
        baseClass: 'fancybox-xl',
        iframe: {
            preload: false
        },
        arrows: false,
        infobar: false,
        smallBtn: true
    });
});

See how it sets the default type to iframe? You can find those configuration options from Fancybox documentation. Not to forgot those 3 base classes styles (I'm using Sass):

.fancybox-md {
    .fancybox-content {
        max-width: 36.75rem;
    }
}

.fancybox-lg {
    .fancybox-content {
        max-width: 65.625rem;
    }
}

.fancybox-xl {
    .fancybox-content {
        max-width: 78.75rem;
    }
}

4.Create links to open modal

Now you can create links with any of those fancybox trigger classes:

<a href="@Url.Action("details", "order", new { area = "", id = item.Id })"
    class="popup-fancy">
    See Order Details
</a>

I assume you have the order controller and details action method all setup to return a view that uses the _PopupLayout, then when the user clicks on the link, instead of the regular redirect to the page using standard layout, the page content should be loaded into the fancybox modal.

For example:

enter image description here

If you can only use bootstrap modal??

In that case, you will have to create a modal template (probably in the layout so that it can be called anywhere) with an iframe inside. And then on link clicked, you use javascript to set the source of the iframe and manually popup the modal.

Sample of modal template

<div id="fancy-modal" class="modal fade" tabindex="-1" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <iframe src="" frameborder="0"></iframe>
        </div>
    </div>
</div>

Then on the page where you generate links, instead to generate actual links, you will have to generate the modal triggers:

<a href="#" class="fancy-modal-trigger"
    data-iframe-src="@Url.Action("details", "order", new { area = "", id = item.Id })">
    See Order Details
</a>

See here you put the actual link to your view on a data-attribute instead of href, because you don't want the link to actually navigate to the destination.

$(function() {
    $('a.fancy-modal-trigger').click(function() {
        let iframeSrc = $(this).data('iframe-src'),
            $fancyModal = $('#fancy-modal');

        $fancyModal.find('iframe').prop('src', iframeSrc);
        $fancyModal.modal('show');

        return false;
    });
});

DISCLAIM: this is not yet tested.

Upvotes: 2

Related Questions