Karl Karl - 1 month ago 17
Javascript Question

Featherlight, JavaScript source for dynamic content

I'm evaluating Featherlight lightbox and I'm not able to implement code that satisfies my use case. I need a lightbox that will be used as a report viewer which displays dynamically created content assigned to a JavaScript variable. The value of the string is a valid HMTL5 page.

I've looked at the iframe example, but it depends upon a static iframe being in the DOM. That's not what I need.

I've reviewed this GitHub issue and this jsfiddle and I'm not able to successfully modify the fiddle to display a string.

This is an example of the string I would like to display:

var s = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Title of the document</title></head><body><p>Content of the document......</p></body></html>';


Is this possible and if so how?

I expect that
$.featherlight()
will be called manually in response to a button click.

Answer

The solution I came up with was to modify the Featherlight source code in 2 places as indicated in this block of code (currently around line 383).

        iframe: {
            process: function(url) {
                var deferred = new $.Deferred();
                var $content = $('<iframe/>')
                    .hide()
                    .attr('src', url)
                    .attr('id', this.namespace + '-id') // [KT] 10/31/2016
                    .css(structure(this, 'iframe'))
                    .on('load', function() {if ($content.show()) {deferred.resolve($content.show()) } else {deferred.resolve($content)} ; })  // [KT] 10/31/2016

                    // We can't move an <iframe> and avoid reloading it,
                    // so let's put it in place ourselves right now:
                    .appendTo(this.$instance.find('.' + this.namespace + '-content'));
                return deferred.promise();
            }
        },

The id attribute is added to the iframe so content can be added by JavaScript, like this:

    var s = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Title of the document</title></head><body><p>Content of the document......</p></body></html>';
    var oIframe = document.getElementById('featherlight-id');  // Featherlight's iframe
    var iframeDoc = (oIframe.contentDocument || oIframe.contentWindow.document);
    iframeDoc.open();
    iframeDoc.write(s);
    iframeDoc.close();

This then works:

   $.featherlight({iframe: 'about:blank', iframeWidth: '96%' });

The 2nd modification is required so that the url 'about:blank' doesn't raise an error.

I also modified the css so as to get the scroll bars to work as needed.

Edit: the issue with Featherlight not opening an iframe when the url is abount:blank has been fixed as of version 1.5.1.

Edit 2: Using v1.5.1, this works without having to make a modification to Featherlight to add an id to to the iframe:

    var s = '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>Title of the document</title></head><body><p>Content of the document......</p></body></html>';
    $.featherlight({iframe: 'about:blank'});
    var $iframe = $('.featherlight iframe');
    $iframe.ready(function () {
        $iframe.contents().find("body").append(s);
    });

The accepted SO answer was used for this solution.

Comments