59

The AJAX tabs work perfectly well. It's pretty straightforward with that part. However, getting the AJAX UI Dialog modal window to trigger off of a link has been unsuccessful.

Any help in this would be appreciated.

informatik01
  • 16,038
  • 10
  • 74
  • 104

8 Answers8

121

Nothing easier than that man. Try this one:

<?xml version="1.0" encoding="iso-8859-1"?>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
    <link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/themes/base/jquery-ui.css" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
    <style>
        .loading { background: url(/img/spinner.gif) center no-repeat !important}
    </style>
</head>
<body>
    <a class="ajax" href="http://www.google.com">
      Open as dialog
    </a>

    <script type="text/javascript">
    $(function (){
        $('a.ajax').click(function() {
            var url = this.href;
            // show a spinner or something via css
            var dialog = $('<div style="display:none" class="loading"></div>').appendTo('body');
            // open the dialog
            dialog.dialog({
                // add a close listener to prevent adding multiple divs to the document
                close: function(event, ui) {
                    // remove div with all data and events
                    dialog.remove();
                },
                modal: true
            });
            // load remote content
            dialog.load(
                url, 
                {}, // omit this param object to issue a GET request instead a POST request, otherwise you may provide post parameters within the object
                function (responseText, textStatus, XMLHttpRequest) {
                    // remove the loading class
                    dialog.removeClass('loading');
                }
            );
            //prevent the browser to follow the link
            return false;
        });
    });
    </script>
</body>
</html>

Note that you can't load remote from local, so you'll have to upload this to a server or whatever. Also note that you can't load from foreign domains, so you should replace href of the link to a document hosted on the same domain (and here's the workaround).

Cheers

jek
  • 2,406
  • 1
  • 18
  • 27
  • @FFish updated answer with a note about cross domain ajax. You cannot just copy'n'paste the source unless you can upload files to http://www.google.com/ ;) – jek Oct 01 '10 at 12:41
  • Ok, cheers. Got it working on localhost (XAMPP) loading a file with a relative path. – FFish Oct 02 '10 at 10:35
  • 2
    jquery.load does not seem to ejecute the javascript contained in the remote content – Guido Jan 09 '11 at 20:53
  • 1
    regarding embedded tags i've never got any problems to get those executed. even multiple occurences worked fine. nevertheless debugging those script chunks is indeed a hazzle, e.g. a syntax error won't show as js error in the browsers console but just avoids the script execution. – jek Jan 18 '11 at 09:17
  • curious - why doesn't the 'nothing easier than this' answer (above) not work? it looks logical? http://206.251.38.181/jquery-learn/ajax/iframe.html –  Mar 12 '11 at 11:34
  • With this solution I can see the div with the response from the ajax call, inserted on the page before dialog is opened. The solution from nicktea does not have this flickering issue. – rlovtang May 16 '11 at 13:10
  • @rlovtang: The "display:hidden" style attribute should prevent this, maybe you're missing the attribute? Beside nickteas solution is missing the links href attribute reference it's also a good approach. So use what works best for ya – jek May 17 '11 at 07:22
  • @jek I have "display:hidden", but I found out that the flickering only appear if the ajax-loaded content pulls in a javascript file. It didn't need to pull in that javascript file, so I removed it. Both solutions works fine now. – rlovtang May 19 '11 at 08:49
  • It seems this solution seems to keep creating divs and allows you to click on the link multiple times creating more divs – Mike Henke Sep 06 '11 at 15:56
  • if do not want to create a POST request, but a GET request instead, ommit the second parameter of the $.load function ('{}'). This inserts an (empty) object to be sent to the server and will automatically create a POST – giorgio Oct 05 '11 at 11:47
  • @Mike and giorgio I've adjusted my solution accordingly, thanks for your comments. – jek Oct 21 '11 at 08:54
  • The problem that I see with this solution is that you first make the AJAX call and open the dialog after the AJAX request is complete which means that if the AJAX call takes a while to complete (slow connection, high server load, etc...) clicking on your link will seem unresponsive. I think opening the dialog before the AJAX request is done would be much better. You can then also add a loading... text or spinner while its loading. – Zaptree Jan 26 '12 at 17:29
  • @Zaptree Indeed. But with a little line juggling one would get around this. In fact I've done it that way in a commercial project. I'll update the code to incorporate your suggestion. – jek Jan 26 '12 at 19:16
  • [I found this answer more useful.](http://stackoverflow.com/questions/3837166/jquery-load-modal-dialog-contents-via-ajax) – mawburn Feb 25 '14 at 15:39
34

To avoid adding extra divs when clicking on the link multiple times, and avoid problems when using the script to display forms, you could try a variation of @jek's code.

$('a.ajax').live('click', function() {
    var url = this.href;
    var dialog = $("#dialog");
    if ($("#dialog").length == 0) {
        dialog = $('<div id="dialog" style="display:hidden"></div>').appendTo('body');
    } 

    // load remote content
    dialog.load(
            url,
            {},
            function(responseText, textStatus, XMLHttpRequest) {
                dialog.dialog();
            }
        );
    //prevent the browser to follow the link
    return false;
});`
CGK
  • 2,662
  • 21
  • 24
  • 3
    Good point indeed.. would you mind if I include this tweak in my original answer? – jek Feb 18 '11 at 09:08
  • The following page diggs nicely into such issues and uses jQuery's one() function to accomplish the same functionality: http://blog.nemikor.com/category/jquery-ui/jquery-ui-dialog/ Since it uses dialog('open') it does not need special close() treatment. – Richard Kiefer Mar 20 '12 at 14:43
25

//Properly Formatted

<script type="text/Javascript">
  $(function ()    
{
    $('<div>').dialog({
        modal: true,
        open: function ()
        {
            $(this).load('mypage.html');
        },         
        height: 400,
        width: 600,
        title: 'Ajax Page'
    });
});

Developer
  • 8,390
  • 41
  • 129
  • 238
nicktea
  • 251
  • 3
  • 2
11

Just an addition to nicktea's answer. This code loads the content of a remote page (without redirecting there), and also cleans up when closing it.

<script type="text/javascript">
    function showDialog() {
        $('<div>').dialog({
            modal: true,
            open: function () {
                $(this).load('AccessRightsConfig.htm');
            },
            close: function(event, ui) {
                    $(this).remove();
                },
            height: 400,
            width: 600,
            title: 'Ajax Page'
        });

        return false;
    }
</script>
Andreas
  • 705
  • 10
  • 22
5

Neither of the first two answers worked for me with multiple elements that can open dialogs that point to different pages.

This feels like the cleanest solution, only creates the dialog object once on load and then uses the events to open/close/display appropriately:

$(function () {
      var ajaxDialog = $('<div id="ajax-dialog" style="display:hidden"></div>').appendTo('body');
      ajaxDialog.dialog({autoOpen: false});
      $('a.ajax-dialog-opener').live('click', function() {
          // load remote content
          ajaxDialog.load(this.href);
          ajaxDialog.dialog("open");
          //prevent the browser from following the link
          return false;
      });
}); 
Cory
  • 22,772
  • 19
  • 94
  • 91
  • 1
    You can actually prevent the default action in the function by using: `$('..').live('click', function(event) { event.preventDefault(); ... });` This way you can omit the `return false;` and prevent accidental triggery of the default `click` event. – plaes Dec 13 '11 at 09:29
  • As stated in response to CGK's answer, you may also be interested in this solution: http://blog.nemikor.com/2009/08/07/creating-dialogs-on-demand/#comments especially for multiple dialog elements – Richard Kiefer Mar 20 '12 at 14:51
0

curious - why doesn't the 'nothing easier than this' answer (above) not work? it looks logical? http://206.251.38.181/jquery-learn/ajax/iframe.html

0

I have combinded few of the answer and came up with below is JQuery code to open the external url in modal dialog box.

<html>
<head>
<script src="https://code.jquery.com/jquery-1.9.1.min.js" integrity="sha256-wS9gmOZBqsqWxgIVgA8Y9WcQOa7PgSIX+rPA0VL2rbQ=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js" integrity="sha256-PsB+5ZEsBlDx9Fi/GXc1bZmC7wEQzZK4bM/VwNm1L6c=" crossorigin="anonymous"></script>
<link rel="stylesheet" type="text/css" href="https://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css">
<body>
    <a href="https://wikipedia.com/" class="test">comment #1</a>
    <br>
    <a href="https://ebay.com/" class="test">comment #2</a>
    <br>
    <a href="https://ask.com/" class="test">comment #3</a>
    <br>
    <a class="ajax" href="https://api.github.com">Open github</a>
    <br>
    <a class="ajax" href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">Open code google</a>
    <br>
    <a class="ajax" href="https://enable-cors.org/">Open enable-cors</a>
    <br>
    <div id="somediv" title="this is a dialog" style="display:none;">
        <iframe id="thedialog" width="350" height="350"></iframe>
    </div>
    <script type="text/javascript">
        $(document).ready(function () {
        $(".test").click(function () 
        {
            var url = $(this).attr("href");
            return openDialogwithiFrame(url);
        });
        });
    </script>
    <script type="text/javascript">
        $(function (){
            $('a.ajax').click(function() {
                var url = this.href;
                return openDialogwithiFrame(url);
            });
        });
        
        function openDialogwithiFrame(url)
        {
            $("#thedialog").attr('src', url);
            $("#somediv").dialog({
            width: 400,
            height: 450,
            modal: true,
            close: function () {
            $("#thedialog").attr('src', "about:blank");
            }
            });
            return false;
        }
        
        function openDialogwithoutiFrame(url)
        {
                // show a spinner or something via css
                var dialog = $('<div style="display:none" class="loading"></div>').appendTo('body');
                // open the dialog
                dialog.dialog({
        // add a close listener to prevent adding multiple divs to the document
                    close: function(event, ui) {
                        // remove div with all data and events
                        dialog.remove();
                    },
                    modal: true
                });
                // load remote content
                dialog.load(
                    url, 
                    //{},  omit this param object to issue a GET request instead a POST request, otherwise you may provide post parameters within the object
                    function (responseText, textStatus, XMLHttpRequest) {
                        // remove the loading class
                        dialog.removeClass('loading');
                    }
                );
                //prevent the browser to follow the link
                return false;
        }
    </script>
</body>
</html>

The code has two function.

  1. openDialogwithiFrame(url) :- This can open any external url in the model dialog. But it uses iframe.
  2. openDialogwithoutiFrame(url):-This also open the external urls in the model dialog but one which has header “Access-Control-Allow-Origin” to correct value. I have put such url in the code for samples. This setting needs to be done at web server. Ref https://medium.com/pareture/simple-local-cors-test-tool-544f108311c5. For setting header “Access-Control-Allow-Origin” at Apache web server following below should de added in .htaccess of Apache server.

    Header set Access-Control-Allow-Origin “*” //Replace domain of host sites separated by comma for *
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
    Header always set Access-Control-Allow-Headers "content-type "
    Header always set Access-Control-Allow-Credentials "true"
skvp
  • 1,940
  • 1
  • 20
  • 25
-1
<a href="javascript:void(0)" onclick="$('#myDialog').dialog();">
  Open as dialog
</a>

<div id="myDialog">
I have a dialog!
</div>

See the example I posted on jsbin.com.

cgp
  • 41,026
  • 12
  • 101
  • 131
  • 1
    Actually, I'm not sure this is what you're looking for, I'll come back and update unless someone else picked it up. Can you clarify what is causing the issue? – cgp Apr 30 '09 at 21:04