0

I have successfully initialized a jQuery DataTable in an iframe, however if I try to run a function in the iframe on the same domain it reinitializes the DataTable instead of using the existing one. How can I fix this?

My code in the JS file of the Iframe:

$(document).ready(function(){
    listTable.initDataTables();
});

var listTable = {
    initDataTables: function() {
        $.each($('.dataTable'), function(){
            var jqTable = $(this);

            // Define the columns
            var columns = [];
            var columnHeadings = jqTable.find('thead > tr:eq(1) > th');
            $.each(columnHeadings, function(){
                var code = $(this).attr('data-code');
                var column = { data: code, defaultContent: '' };
                columns.push(column);
            });

            // Initiate the table
            var dataTable = jqTable.DataTable({
                'ajax': {
                    'url': '/get-data',
                    'type' : 'GET'
                },
                'columns': columns,
                'responsive': true,
                'scroller': false,
                'select': true,
                'bLengthChange': false,
                'bFilter': true,
                'bInfo': true,
            });
        });
    }
};

When I run the following code in a window without an iframe, all works well:

$('table').DataTable().ajax.url();
// returns '/get-data'

But when I run the following code from a parent window that contains an iframe, NULL gets returned:

$('iframe').contents().find('table').DataTable().ajax.url()
// returns NULL

I also notice that when I run the code from a parent window, navigation bars get added a second time. So it looks like the DataTable() function is creating a new instance on the same table.

Hans
  • 528
  • 1
  • 8
  • 29
  • Probably, the security policy of your web browser that's blocking scripting between frames/iframes. – ADreNaLiNe-DJ Jan 27 '16 at 09:58
  • @ADreNaLiNe-DJ The parent and iframe are on the same domain. I can get the correct table as a jQuery object returned and I am also able to run a function in the iframe which should return the Ajax Url, but still NULL is returned. – Hans Jan 27 '16 at 10:02
  • jQuery selectors and find function returns an array of matching elements; So calling "Datable" on an array should not work. Try something like this _$($('iframe').contents().find('table').get(0)).DataTable().ajax.url()_ – ADreNaLiNe-DJ Jan 27 '16 at 10:16
  • "$($('iframe').contents().find('table').get(0))" returns the table element, but "$($('iframe').contents().find('table').get(0)).DataTable().ajax.url()" still returns null. – Hans Jan 27 '16 at 10:20
  • Try to make your variable _dataTable_ global: declare it outside _listTable_ and then access it. – ADreNaLiNe-DJ Jan 27 '16 at 10:25
  • If you open the iframe page individually, did the datatables loads correctly ? – ADreNaLiNe-DJ Jan 27 '16 at 11:00
  • Solved by applying your solution below! – Hans Jan 27 '16 at 13:06

1 Answers1

0

I made a change in the selector of your headings (eq(0) instead of eq(1)) in order to make datatables to load properly the table.

Here is the code i made locally: main.html:

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <link href="http://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="http://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function()
        {
            $('#example').on("click", function() {
                var ajaxurl = document.getElementById("MyIframe").contentWindow.myDataTable.ajax.url();
                alert(ajaxurl);
            });
        });
    </script>
</head>
<body>
    <input type="button" id="example" />
    <iframe id="MyIframe" src="iframe.html"></iframe>
</body>
</html>

iframe.html:

<!DOCTYPE html>
<html>
<head>
    <title>Example</title>
    <link href="http://cdn.datatables.net/1.10.10/css/jquery.dataTables.min.css" rel="stylesheet" type="text/css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script src="http://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            listTable.initDataTables();
        });
        var myDataTable;
        var listTable = {
            initDataTables: function() {
                $('.dataTable').each(function(){
                    var jqTable = $(this);

                    // Define the columns
                    var columns = [];
                    var columnHeadings = jqTable.find('thead > tr:eq(0) > th');
                    $.each(columnHeadings, function(){
                        var code = $(this).attr('data-code');
                        var column = { data: code, defaultContent: '' };
                        columns.push(column);
                    });

                    // Initiate the table
                    myDataTable = jqTable.DataTable({
                        'ajax': {
                            'url': 'get-data.json',
                            'type' : 'GET'
                        },
                        'columns': columns,
                        'responsive': true,
                        'scroller': false,
                        'select': true,
                        'bLengthChange': false,
                        'bFilter': true,
                        'bInfo': true,
                    });
                });
            }
        };
</script>
</head>
<body>
    <input type="text" id="example" />
    <table id="MyDataTable" class="dataTable">
        <thead>
            <tr>
                <th>Column 1</th>
                <th>Column 2</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Row 1 Data 1</td>
                <td>Row 1 Data 2</td>
            </tr>
            <tr>
                <td>Row 2 Data 1</td>
                <td>Row 2 Data 2</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

With an empty file "get-data.json".

When you click on the button, it alerts you with "get-data.json".

ADreNaLiNe-DJ
  • 4,787
  • 3
  • 26
  • 35
  • Thanks! Moving the datatable to a global variable fixed it! For this specific scenario, I created a global array because there can be multiple datatables on a single page. – Hans Jan 27 '16 at 13:05