zazvorniki
zazvorniki

Reputation: 3602

Remote Content with Links in Bootstrap Modal

I have a bunch of Bootstrap modal windows on a site I'm working on that are loading remote content. This is working perfectly. However, my boss has informed me that the links within those modals cannot go to a new page, they must reload in the modal window.

I have tried a few things with no luck.

First, I have the modal link inside the modal

<a data-toggle='modal' class='modalBox' data-target='#largeModal'
href='link here'>Link</a>

This link does not work, Bootstrap.js throws this error..

TypeError: 'undefined' is not a function (evaluating 'b.preventDefault()')

So I tried changing the Id to a different modal window I have on the page and it does pop up behind the modal window that is already there. Which is not exactly what I need, but is promising.

Is there a way around this so the content can load in the same modal window?

Upvotes: 8

Views: 6376

Answers (5)

Frugan
Frugan

Reputation: 389

This is the solution i have adopted. It works with:

  • jQuery v1.11.2
  • jQuery Migrate v1.2.1
  • Bootstrap v3.3.1

Main page HTML:

<!doctype html>
<html class="no-js" lang="">
<head>

<!-- Your code here -->

</head>
<body>

<ul>
  <li><a href="/page-1" data-target="bs-modal-lg" class="modal-trigger" data-toggle="modal">Modal page #1</a></li>
  <li><a href="/page-2" data-target="bs-modal-md" class="modal-trigger" data-toggle="modal">Modal page #2</a></li>
</ul>

<div class="modal fade bs-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content"></div>
  </div>
</div>

<div class="modal fade bs-modal-md" tabindex="-1" role="dialog" aria-labelledby="myMediumModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-md">
    <div class="modal-content"></div>
  </div>
</div>

<div class="modal fade bs-modal-sm" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-sm">
    <div class="modal-content"></div>
  </div>
</div>

<!-- Javascript here -->

</body>
</html>

Modal page #1 HTML:

<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
    <h4 class="modal-title" id="myLargeModalLabel">Modal page #1</h4>
</div>
<div class="modal-body">
    <ul>       
        <li><a href="/" target="_parent">Main page</a></li>
        <li><a href="/page-2" data-target="bs-modal-md">Modal page #2</a></li>
    </ul>
</div>

Modal page #2 HTML:

<div class="modal-header">
    <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
    <h4 class="modal-title" id="myLargeModalLabel">Modal page #2</h4>
</div>
<div class="modal-body">
    <ul>       
        <li><a href="/" target="_parent">Main page</a></li>
        <li><a href="/page-1" data-target="bs-modal-lg">Modal page #1</a></li>
    </ul>
</div>

Bootstrap 3 Modal Vertically Centered (see here http://codepen.io/ahliang85/pen/aFteG/):

(function($) {
    $.extend({
        adjustModalMaxHeightAndPosition : function(focus) {
            $('.modal').each(function(){
              if($(this).hasClass('in') == false){
                $(this).show();
              };
              var contentHeight = $(window).height() - 60;
              var headerHeight = $(this).find('.modal-header').outerHeight() || 2;
              var footerHeight = $(this).find('.modal-footer').outerHeight() || 2;

              $(this).find('.modal-content').css({
                'max-height': function () {
                  return contentHeight;
                }
              });

              $(this).find('.modal-body').css({
                'max-height': function () {
                  return (contentHeight - (headerHeight + footerHeight));
                }
              });

              $(this).find('.modal-dialog').css({
                'margin-top': function () {
                  return -($(this).outerHeight() / 2);
                },
                'margin-left': function () {
                  return -($(this).outerWidth() / 2);
                }
              });
              if($(this).hasClass('in') == false){
                $(this).hide();
              };
            });
        }
    });
})(jQuery);

$(window).resize($.adjustModalMaxHeightAndPosition).trigger("resize");

Javascript:

(function($) {
    $('.modal-trigger').click(function(e){
        e.preventDefault();

        var href = $(this).attr('href');    
        var target = $(this).data('target');

        $('.' + target + ' .modal-content').load(href, function(result){
            $('.' + target).modal({show:true});
            $('.' + target).on('loaded.bs.modal', $.adjustModalMaxHeightAndPosition());
        });
    });

    $('.modal').on('click', 'a', function (e) {
        e.preventDefault();

        var href = $(this).attr('href');        
        var target = $(this).data('target');

        $('.' + target + ' .modal-content').html('').load(href, function(result){
            $('.' + target).on('loaded.bs.modal', $.adjustModalMaxHeightAndPosition());
        });
    });
})(jQuery);

Here http://naturarisponde.it you can see a working example by clicking on "Privacy Policy" and "Cookie Policy" at the bottom of page.

Upvotes: 0

Andrew Theken
Andrew Theken

Reputation: 3480

I'm going to assume you have jQuery available to you, and that all links in the modals are standard anchor tags (<a href="...">Link</a>)

I'm also going to assume the modal structure as defined here: http://getbootstrap.com/javascript/#modals

The simplest way to do this is to configure delegates on the links, prevent default, and to load the content in the modal body element. This will require the fewest modifications to the modal content, avoids isolating the content in iframes (therefore breaking styling), and generally is pretty clean solution:

jQuery('body').delegate('click', '.modal-body a', function(evt){
    //prevent the browser from navigating to the url for the 'a'
    evt.preventDefault();
    //find the parent that is the "modal-body" of this link
    //load the href html into that parent.
    $(this).parent('.modal-body').load($(this).attr('href'));
});

The above only needs to be run one time, on page ready, and this will handle all existing and future modals. One caveat is that if the links go to an anchor, rather than a new page, this will not work (i.e. #somepointinapage), but for most cases it'll work well.

Upvotes: 0

user3437379
user3437379

Reputation: 89

Just copy paste the code given bellow. You can also change the site to which it is redirected by changing the link in object and embed tag. This can also be done by using iframe instead of embed. Post if you have any further doubts on this

<!DOCTYPE html>   
    <html lang="en">   
    <head>   
    <meta charset="utf-8">   
    <title>Modal Window Example</title>   
    <meta name="description" content="Modal Window example using twitter bootstrap">  
    <link href="twitter-bootstrap/twitter-bootstrap-v2/docs/assets/css/bootstrap.css" rel="stylesheet">   
    <script src="twitter-bootstrap/twitter-bootstrap-v2/docs/assets/js/jquery.js"></script>  
    <script src="twitter-bootstrap/twitter-bootstrap-v2/docs/assets/js/bootstrap-modal.js"></script>  
    </head>  
    <body>  
        <div class="container">  
            <h2>Example of creating Modals with Twitter Bootstrap</h2>  
            <div id="example" class="modal hide fade in" style="display: none;  max-height: 700px; width:800px;">  
                <div class="modal-header">  
                    <a class="close" data-dismiss="modal">×</a>  
                    <h3></h3>  
                </div>  
                <div class="modal-body">  

                </div> 
                <object data=http://www.biomedcentral.com/1472-6823/14/27/abstract width="800 px" height="900 px"> 
                    <embed http://www.biomedcentral.com/1472-6823/14/27/abstract width="800 px" height="900 px"> </embed> 
                    Error: Embedded data could not be displayed. 
                </object> 
                <div class="modal-footer">  
                    <a href="#" class="btn btn-success">Call to action</a>  
                    <a href="#" class="btn" data-dismiss="modal">Close</a>  
                </div>  
            </div>
            <p><a data-toggle="modal" href="#example" class="btn btn-primary btn-large">Launch demo modal</a></p>  
        </div>  


    </body>  
    </html>

You have to include bootstrap-modal.js and bootstraps jquery.js file. which you can get from getbootstrap.com

Upvotes: -1

Hitesh Modha
Hitesh Modha

Reputation: 2790

Onclick call javascript function

<a onclick="loadContent()">Link</a>

Call Javascript function to load data using ajax request:

function loadContent()
{
//You can load data using ajax request
$("#modelBodyId").html('Data')
// If you want to open other modal - $('#largeModal").modal('show');
}

Upvotes: 0

Dirk Lachowski
Dirk Lachowski

Reputation: 3151

As @Chevi suggested, the best option will be to place an iframe inside the modal. There is no need to change your existing page/modal layout as you can insert a new iframe on each klick.

Given you have a bootstrap modal with a link inside the .modal-body you will need something like this:

$('.modal').on("click", "a", function (e) {
    var target = $(this).attr('href');
    $('.modal-body').html('');
    $('<iframe>').attr('src', target).appendTo($('.modal-body'));
    e.preventDefault();
});  

This grabs the href of the clicked link, replaces the .modal-body content with an iframe and sets the iframe's src to the href of the link.

Be aware that the link target must be frameable: No framekillers, no X-Frame-Options (therefore linking to google this way will not work!)

Fiddle: http://jsfiddle.net/445eA/

Upvotes: 5

Related Questions