2

I found I can include my modal markup in the body of my index.php and load it via this line without any problems:

<a data-toggle="modal" href="#modal-add">Add</a>

Assuming, of course, that there's a div somewhere in that page called #modal-add. When I moved that out to its own file (modal-add.html) and try this:

<a data-toggle="modal" href="modal-add.html" data-target="#modal-add">Add</a>

...I can't see that anything is happening. Chrome's developer tools don't register any activity when I click the link. I've created a basic fiddle to demonstrate: http://jsfiddle.net/tmountjr/3bnyq/2/

According to the docs (http://getbootstrap.com/javascript/#modals) that should just work, right? Where am I going wrong? (I'm referencing the Bootstrap js and css files from netdna, and jquery from their site, and everything else on my site is behaving normally, minus this.)

EDIT

Since it appears that fiddle has a built-in cross-domain request, here's a bare-bones setup that anyone with a WAMP server can try:

modal.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css">
    </head>
    <body>
        <p><a href="modaltest.html" data-toggle="modal" data-target="#modal">Click here</a></p>
        <script src="//code.jquery.com/jquery.js"></script>
        <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    </body>
</html>

modaltest.html:

<div id="modal" class="modal fade" role="dialog">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h4 class="modal-title">Add New Designation</h4>
            </div>
            <div class="modal-body">
                <form>
                    <fieldset>
                        <div class="form-group">
                            <label for="add-designation">Designation Description:</label>
                            <input type="text" name="add-designation" id="add-designation" class="form-control" />
                        </div>
                    </fieldset>
                </form>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" id="resetdesignation">Reset</button>
                <button type="button" class="btn btn-primary" id="adddesignation">Add Designation</button>
            </div>
        </div>
    </div>
</div>
tmountjr
  • 1,423
  • 2
  • 22
  • 38
  • You can't do this example in jsfiddle: `XMLHttpRequest cannot load http://jsfiddle.net/TbXgX/3/show/. Origin http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin.` – dr.dimitru Oct 24 '13 at 15:12
  • Thought I saw a similar example where the author was using this technique but upon further review he was handling the clicks within js rather than just from the link. But that doesn't answer the original question, which is: why does something taken straight from Bootstrap's docs not work? – tmountjr Oct 24 '13 at 15:34
  • 1
    I think you have to point `data-target` attribute to element which exists in DOM, and not returned in AJAX-response. And as I know returned result just placed into target with `.html()` method which equal to `innerHTML` which replaces everything inside target. So you can point all links to one Modal (with `id="modal"`) and it's content will be just replaced with AJAX-response. – dr.dimitru Oct 24 '13 at 16:02
  • Ah, I see. You need a placeholder in the main body, and everything else can be streamed in after that. Go ahead and put that in as an answer and I'll accept it. – tmountjr Oct 24 '13 at 19:26

2 Answers2

3

I think you have to point data-target attribute to element which exists in DOM (not returned in AJAX-response).

And as I know returned result just placed into target with .html() method which equal to innerHTML which replaces everything inside target.

So you can point all links to one Modal (with id="modal") and it's content will be just replaced with AJAX-response.

dr.dimitru
  • 2,645
  • 1
  • 27
  • 36
  • Just to clarify in my testing: I put a blank `` at the bottom of the page (still inside the `#container` div) and all my modal includes start with the `` markup. – tmountjr Oct 24 '13 at 20:14
  • Yes you need to return HTML without Modal Container which is `div.modal-content`, so your empty modal is `div.modal.fade > div.modal-dialog` - in acc. to bootstrap 3 docs (http://getbootstrap.com/javascript/#modals) – dr.dimitru Oct 24 '13 at 20:24
  • @mounty Once again - You need to test out everything to clarify - cause this moment is not mentioned in TWBS3 docs. – dr.dimitru Oct 24 '13 at 20:26
  • 1
    Absolutely. Based on what I'm seeing in my project, all the various divs look like they're lining up correctly, and I'm not seeing any unexpected behavior that would indicate something's being pulled incorrectly. – tmountjr Oct 24 '13 at 20:28
  • really appreciate the solution, it worked for me, thank you so much. if it is loaded in the container, it doesnt request the modal again from the server, thats a really nice solution. +1 – A.J. Mar 03 '14 at 12:12
0

As an aside, it's also worth noting that this method (using a remote page as your dialog source) is limited out of the box to one external source. (In other words, if you have three different remote sources it'll only ever load the first one you click.) I tried emptying the #modal div after it closes but that didn't seem to work; the only way I found around it was this fiddle which overrides the default modal behavior, manually loads the content each time, and then displays the modal. For good measure (though I don't think it's required) I empty the div after the modal closes, just so I don't have extra code laying around inside my page. Here's my code:

$("[data-target]").on('click', function(e) {
    e.preventDefault();
    var placeholder = $(this).data('target');
    var target = $(this).attr('href');
    $(placeholder).load(target);
});

$('#modal').on('hidden.bs.modal', function () {
    $("#modal").empty();
});

EDIT

There's an even better solution documented here.

Community
  • 1
  • 1
tmountjr
  • 1,423
  • 2
  • 22
  • 38