Dynamically Set iFrame Height Used Within Child Row

Dynamically Set iFrame Height Used Within Child Row

Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2
edited May 2015 in Editor

I am using an iFrame within the child row function in order to display some content. The content is different for each row within the table and therefore the iFrame height should be different to match the current content. I have the following working for 1 iFrame with 1 iFrame ID. However, I am stuck as to how to pass the current iFrames ID to my function which does the resizing.

<script type="text/javascript">
    $(document).ready(function() {
        var editor = new $.fn.DataTable.Editor({
            "ajax" : {
                "url" : "/uploads/js/datatables/php/speed.php",
                "type" : "POST",
                "data" : function(d) {
                    d.min = $('#min').val();
                    d.max = $('#max').val();
                }
            },
            "table" : "#user",
            "fields" : []
        });

        // View a record
        $('#user').on('click', 'a.editor_view', function(e) {
            e.preventDefault();
        });

        // Delete a record
        $('#user').on('click', 'a.editor_remove', function(e) {
            e.preventDefault();

            editor.message('Are you sure you wish to remove this record?').buttons('Delete').remove($(this).closest('tr'));
        });

        function format(d) {
            return '{/literal}<iframe src="/page-analysis-tabs/?&m=' + d.Id + '" id="idIframe' + d.Id + '" onload="iframeLoaded()" height="100%" width="100%" ></iframe>{literal}';
        }

        var table = $('#user').DataTable({
            "responsive" : true,
            "autoWidth" : true,
            "dom" : "frtip",
            "bSortClasses" : false,
            "processing" : true,
            "serverSide" : true,
            "ajax" : {
                "url" : "/uploads/js/datatables/php/speed.php",
                "type" : "POST",
                "data" : function(d) {
                    d.min = $('#min').val();
                    d.max = $('#max').val();
                }
            },
            "language" : {
                "search" : "_INPUT_",
                "searchPlaceholder" : "Search data...",
                "sLengthMenu" : "_MENU_ per page"
            },
            "order" : [[3, "desc"]],
            "oSearch" : {
                "sSearch" : ""
            },
            "searchDelay" : 1000,
            "columns" : [{
                "data" : "monitor_name",
                "createdCell" : function(td) {
                    $(td).addClass('grey details-control pointer');
                }
            }, {
                "data" : "desktop_speed_result",
                "createdCell" : function(td) {
                    $(td).addClass('grey details-control pointer');
                }
            }, {
                "data" : "mobile_speed_result",
                "createdCell" : function(td) {
                    $(td).addClass('grey details-control pointer');
                }
            }, {
                "data" : "usability_result",
                "createdCell" : function(td) {
                    $(td).addClass('grey details-control pointer');
                }
            }, {
                "data" : "create_date",
                "width" : "90px",
                "createdCell" : function(td) {
                    $(td).addClass('details-control pointer');
                }
            }, {
                "className" : 'details-control',
                "orderable" : false,
                "bSearchable" : false,
                "data" : null,
                "defaultContent" : '<a href="" class="editor_view fontawesome-info fontawesome-lg grey pointer"></a>'
            }, {
                "data" : null,
                "orderable" : false,
                "bSearchable" : false,
                "className" : "center",
                "defaultContent" : '<a href="" class="editor_remove fontawesome-remove fontawesome-lg grey pointer"></a>'
            }, {
                "data" : "monitor_id",
                "targets" : [10],
                "visible" : false,
                "searchable" : true,
                "className" : "never"
            }],
        });
        $('#user tbody').on('click', 'td.details-control', function() {
            var tr = $(this).closest('tr');
            var row = table.row(tr);
            if (row.child.isShown()) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
            } else {
                // Open this row
                row.child(format(row.data())).show();
                tr.addClass('shown');
            }
        });
        $('#user tbody').on('click', 'td.details-control', function() {
            var iFrameID = document.getElementById('idIframe4');
            $("#idIframe4").on("load", function() {
                if (iFrameID) {
                    iFrameID.height = "";
                    iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
                }
            });
        });
    }); 
</script>

As you can see I can dynamically set the iFrame ID using the record number using <iframe src="/page-analysis-tabs/?&m=' + d.Id + '" id="idIframe' + d.Id + '" onload="iframeLoaded()" height="100%" width="100%" ></iframe>

However, I do not know if I can pass this ID to my resizing function.

Is there anyway to achieve what I am trying to do?

Thanks

This question has an accepted answers - jump to answer

Answers

  • allanallan Posts: 61,849Questions: 1Answers: 10,134 Site admin

    I don't use iframes much, but can you attach an onresize DOM0 event to it that will call a function. If so, then you could just pass the row id into the function.

    The other option, possibly better, is it first note, why are you using two different click event handlers for the same element? Why not just have one and base your resize function on the iframe that has been added into the child row after you "open" the row.

    Allan

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Hi Allan,

    Thanks for your advice. The second option sounds good. The reason I currently have two click event handlers is because I am not very adept with javascript and this was the only method I could get to work. My errors I am sure.

    Are there any examples you know of whereby I could see the practice of capturing the open row ID and passing it into my javascript to resize that particular iFrame? In another function I have used this method to capture some information:

            editor.on( 'preSubmit', function ( e, data, action ) {
            if ( action === 'remove' ) {
                var rowData = table.row( this.modifier() ).data();
                id = rowData.monitor_id;
            }
            });
    

    However, I am not using the editor.on preSubmit button on this occasion so I am not sure how to capture my information.

    Thanks

    Chris

  • allanallan Posts: 61,849Questions: 1Answers: 10,134 Site admin

    No example that I'm aware of - that's rather a specific use case!

    However, you could use something like:

    row.child(format(row.data())).show();
    tr.addClass('shown');
    
    var id = row.data().DT_RowId; // change to suit your id parameter name if needed)
    

    and then do whatever is needed with id.

    Allan

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2
    edited May 2015

    Hi Allan,

    I have attempted this:

            $('#speed tbody').on('click', 'td.details-control', function() {
                var tr = $(this).closest('tr');
                var row = table.row(tr);
                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    tr.removeClass('shown');
                } else {
                    // Open this row
                    row.child(format(row.data())).show();
                    tr.addClass('shown');
                    var id = row.data().DT_RowId;
                }
            });
            $('#speed tbody').on('click', 'td.details-control', function() {
                var iFrameID = document.getElementById('idIframe'+id);
                $('#idIframe'+id).on("load", function() {
                    if (iFrameID) {
                        iFrameID.height = "";
                        iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
                    }
                });
            });
    

    But in my console I get the error "Uncaught ReferenceError: id is not defined"

    Any idea why?

    Thanks

    Chris

  • allanallan Posts: 61,849Questions: 1Answers: 10,134 Site admin
    Answer ✓

    Because it isn't ;-). id is locally scoped in the first click event handler, so the second one has no access to it.

    I would go back again to the point about there being two identical event handlers - reduce it to one. Put the code for the second one after your var id.

    Allan

  • Restful Web ServicesRestful Web Services Posts: 202Questions: 49Answers: 2

    Great, it works thanks. I didn't realise the var was only locally scoped. This is working for me now:

            $('#speed tbody').on('click', 'td.details-control', function() {
                var tr = $(this).closest('tr');
                var row = table.row(tr);
                if (row.child.isShown()) {
                    // This row is already open - close it
                    row.child.hide();
                    tr.removeClass('shown');
                } else {
                    // Open this row
                    row.child(format(row.data())).show();
                    tr.addClass('shown');
                    var id = row.data().DT_RowId;
                    var iFrameID = document.getElementById('idIframe_'+id);
                    $('#idIframe_'+id).on("load", function() {
                    if (iFrameID) {
                    iFrameID.height = "";
                    iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
                    }
                    });
                }
            });  
    
This discussion has been closed.