Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to show multiple dialog polyfill?

I have script to open dialog polyfill :

window.modalDialog = function (url, arg, opt) {
        url = url || ''; //URL of a dialog
        arg = arg || null; //arguments to a dialog
        opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles

        var caller = modalDialog.caller.toString();
        var dialog = document.body.appendChild(document.createElement('dialog'));
        var splitter = opt.split(",");
        dialog.setAttribute('style', splitter[0].replace(/dialog/gi, ''));
        dialog.innerHTML = '<a href="#" id="dialog-close">&times;</a><iframe id="dialog-body" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
        document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
        document.getElementById('dialog-close').addEventListener('click', function (e) {
            e.preventDefault();
            dialog.close();
        });
        dialog = document.querySelector('dialog');
        dialogPolyfill.registerDialog(dialog);

        function addListeners() {
            document.querySelector('dialog').addEventListener('mousedown', mouseDown, false);
            window.addEventListener('mouseup', mouseUp, false);
        }

        function mouseUp()
        {
            window.removeEventListener('mousemove', divMove, true);
        }

        function mouseDown(e) {
            window.addEventListener('mousemove', divMove, true);
        }

        function divMove(e) {
            var div = document.querySelector('dialog');
            div.style.position = 'absolute';
            div.style.top = e.clientY + 'px';
            div.style.left = e.clientX + 'px';
        }

        addListeners();
        dialog.showModal();
        dialog.addEventListener('close', function () {
            var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
            document.body.removeChild(dialog);
            nextStmts[0] = nextStmts[0].replace(/(window\.)?modalDialog\(.*\)/g, JSON.stringify(returnValue));
            eval('{\n' + nextStmts.join('\n'));
        });
        throw 'Execution stopped until modalDialog is closed';
    };

when I call this script, dialog-body got replaced with new url instead create new dialog. How can i create multiple dialog?

EDIT

My biggest problem is that my dialogs has the same parent (caller), so in dialog polyfill js library, there's script to check if there are dialogs or not in parent document, if yes, then throw warning Failed to execute showModal on dialog: The element is already open, and therefore cannot be opened modally.

EDIT

I have created the jsfiddle, but i dont know how to call external source website from jsfiddle. https://jsfiddle.net/godofrayer/gvLpLjkq/

like image 207
Randyka Yudhistira Avatar asked Sep 29 '17 03:09

Randyka Yudhistira


1 Answers

I modified your example a little bit and now you can open multiple dialogs. The problem was the getElementById. An id has to be unique in a document. So I have organized the dialogs in an array, and the ID-elements now contain the index of the array at the the end of the id: id="dialog-close'+dlgIndex+'".

My modification is here

Here you can see the main changes:

var dlgs = [];
    window.showModalDialog = window.showModalDialog || function(url, arg, opt) {
        url = url || ''; //URL of a dialog
        arg = arg || null; //arguments to a dialog
        opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles        
        var caller = showModalDialog.caller.toString();

        var dialog = document.body.appendChild(document.createElement('dialog'));
        // Adds the Dialog to an Array of Dialogs
        var dlgIndex = dlgs.length;
        dlgs[dlgIndex] = dialog;
        dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
        dialog.innerHTML = '<a href="#" id="dialog-close'+dlgIndex+'" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">&times;</a><iframe id="dialog-body'+dlgIndex+'" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
        document.getElementById('dialog-body'+dlgIndex).contentWindow.dialogArguments = arg;
        document.getElementById('dialog-close'+dlgIndex).addEventListener('click', function(e) {
            e.preventDefault();
            dialog.close();
        });
        dialog.showModal();
        //if using yield
        if(caller.indexOf('yield') >= 0) {
            return new Promise(function(resolve, reject) {
                dialog.addEventListener('close', function() {
                    var returnValue = document.getElementById('dialog-body'+dlgIndex).contentWindow.returnValue;
                    document.body.removeChild(dialog);
                    resolve(returnValue);
                });
            });
        }
        //if using eval
        var isNext = false;
        var nextStmts = caller.split('\n').filter(function(stmt) {
            if(isNext || stmt.indexOf('showModalDialog(') >= 0)
                return isNext = true;
            return false;
        });
        dialog.addEventListener('close', function() {
            var returnValue = document.getElementById('dialog-body'+dlgIndex).contentWindow.returnValue;
            document.body.removeChild(dialog);
            nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue));
            eval('{\n' + nextStmts.join('\n'));
        });
        //throw 'Execution stopped until showModalDialog is closed';
    };
})();

var showDialog = function() {
    window.showModalDialog("https://heise.de/");
  console.log("ShowSecond!!!")
  window.showModalDialog("https://www.heise.de/newsticker/meldung/Einstweilige-Verfuegung-Vodafone-muss-Kinox-to-sperren-3966023.html");
};

Hope this helps.

like image 115
sweting Avatar answered Oct 23 '22 19:10

sweting