MFPanels / 1.3 / js / mfpanel.js
file last updated : 2023-06-06
function MFPanels() {

    var _paneldragger = null, _paneldragMax;

    function getUniqueID(prefix) {
        var n = 1;
        while (document.getElementById(prefix + n)) n++;
        return prefix + n;
    }

    function doRepositionDividers() {
        var draggers = document.getElementsByClassName('paneldragger');
        for (var d = 0; d < draggers.length; d++) {
            var panel = document.getElementById(draggers[d].getAttribute('data-elem'));
            var container=panel.parentElement;
            if (/\bdragger-h\b/.test(draggers[d].classList)) {
                var w=parseInt(draggers[d].getBoundingClientRect().width);
                draggers[d].style.top = (panel.getBoundingClientRect().top) + 'px';
                draggers[d].style.left = (panel.getBoundingClientRect().left + panel.getBoundingClientRect().width - w/2) + 'px';
                draggers[d].style.height = (panel.getBoundingClientRect().top + panel.getBoundingClientRect().height) + 'px';
            }
            if (/\bdragger-v\b/.test(draggers[d].classList)) {
                var h=parseInt(draggers[d].getBoundingClientRect().height);
                draggers[d].style.left = (panel.getBoundingClientRect().left) + 'px';
                draggers[d].style.top = (panel.getBoundingClientRect().top + panel.getBoundingClientRect().height - h/2) + 'px';
                draggers[d].style.width = (+panel.getBoundingClientRect().width) + 'px';
            }
        }
    }


    window.addEventListener('resize', function () {
        doRepositionDividers();
    });
    window.addEventListener('scroll', function () {
        doRepositionDividers();
    });

    return {
        init: function() {
            var container;
            var panels = document.getElementsByClassName('resizable-e');
            for (var i = 0; i < panels.length; i++) {
                var panel = panels[i];
                container=panel.parentElement;
                if (!panel.id) panel.id = getUniqueID('left');
                var dragger = document.createElement('div');
                dragger.className = 'paneldragger dragger-h';

                dragger.style.top = panel.getBoundingClientRect().top + 'px';
                dragger.style.height = ( container.getBoundingClientRect().height ) + 'px';
                dragger.setAttribute('data-elem', panel.id);
                dragger.id = getUniqueID('dragger');
                document.body.appendChild(dragger);
                var w=parseInt(dragger.getBoundingClientRect().width);
                dragger.style.left = (panel.getBoundingClientRect().left + panel.getBoundingClientRect().width - w/2) + 'px';
                panel.setAttribute('data-dragger', dragger.id);

                panel.style.width=(panel.getBoundingClientRect().width / container.getBoundingClientRect().width * 100)+'%';
                //panel.style.height='100%';
                var nextp=panel.nextElementSibling;
                if ( nextp ) nextp.style.width=(nextp.getBoundingClientRect().width / container.getBoundingClientRect().width * 100)+'%';
            }


            var panels = document.getElementsByClassName('resizable-s');
            for (var i = 0; i < panels.length; i++) {
                var panel = panels[i];
                container=panel.parentElement;
                if (!panel.id) panel.id = getUniqueID('top');
                var dragger = document.createElement('div');
                dragger.className = 'paneldragger dragger-v';

                dragger.style.left = panel.getBoundingClientRect().left + 'px';
                dragger.style.width = container.getBoundingClientRect().width + 'px';
                dragger.setAttribute('data-elem', panel.id);
                dragger.id = getUniqueID('dragger');
                document.body.appendChild(dragger);
                var h=parseInt(dragger.getBoundingClientRect().height);
                dragger.style.top = (panel.getBoundingClientRect().top + panel.getBoundingClientRect().height - h/2) + 'px';
                panel.setAttribute('data-dragger', dragger.id);

                panel.style.height=(panel.getBoundingClientRect().height / container.getBoundingClientRect().height * 100)+'%';
                //panel.style.width='100%';
                var nextp=panel.nextElementSibling;
                if ( nextp ) nextp.style.height=(nextp.getBoundingClientRect().height / container.getBoundingClientRect().height * 100)+'%';
            }


            var draggers = document.getElementsByClassName('paneldragger');
            for (var d = 0; d < draggers.length; d++) {
                draggers[d].addEventListener('mousedown', function (e) {
                    var dragger = e.target;
                    if (/\bdragger-h\b/.test(dragger.classList)) {
                        _paneldragger = dragger;
                        var x = _paneldragger.getBoundingClientRect().left;
                        _paneldragger.setAttribute('data-startdrag', x);
                        _paneldragger.setAttribute('data-dragging', 1);

                        var leftElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                        var rightElem = leftElem.nextElementSibling;
                        _paneldragMax = rightElem.getBoundingClientRect().right;
                    }
                    if (/\bdragger-v\b/.test(dragger.classList)) {
                        _paneldragger = dragger;
                        var y = _paneldragger.getBoundingClientRect().top;
                        _paneldragger.setAttribute('data-startdrag', y);
                        _paneldragger.setAttribute('data-dragging', 1);

                        var topElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                        var bottomElem = topElem.nextElementSibling;
                        _paneldragMax = bottomElem.getBoundingClientRect().bottom;
                    }
                });
            }


            window.addEventListener('mousemove', function (e) {
                if (_paneldragger) {
                    if (/\bdragger-h\b/.test(_paneldragger.classList)) {
                        var x = parseInt(e.clientX);
                        if (x < _paneldragMax) {
                            if (_paneldragger.getAttribute('data-dragging') == 1 && x > 0) {
                                _paneldragger.setAttribute('data-startdrag', x);
                                var w=parseInt(_paneldragger.getBoundingClientRect().width);
                                _paneldragger.style.left = (x - w/2) + 'px';
                            }
                        }
                        var selection = window.getSelection();
                        if (selection.rangeCount > 0) selection.removeAllRanges();
                    }
                    if (/\bdragger-v\b/.test(_paneldragger.classList)) {
                        var y = parseInt(e.clientY);
                        if (y < _paneldragMax) {
                            if (_paneldragger.getAttribute('data-dragging') == 1 && y > 0) {
                                _paneldragger.setAttribute('data-startdrag', y);
                                var h=parseInt(_paneldragger.getBoundingClientRect().height);
                                _paneldragger.style.top = (y - h/2) + 'px';
                            }
                        }
                        var selection = window.getSelection();
                        if (selection.rangeCount > 0) selection.removeAllRanges();

                    }
                }
            });


            window.addEventListener('mouseup', function (e) {
                if (_paneldragger) {
                    if (/\bdragger-h\b/.test(_paneldragger.classList)) {
                        var leftElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                        var rightElem = leftElem.nextElementSibling;

                        _paneldragger.setAttribute('data-dragging', 0);

                        var ww = window.innerWidth;
                        var x0 = _paneldragger.getAttribute('data-startdrag');
                        var x = _paneldragger.getBoundingClientRect().left;
                        var left = leftElem.getBoundingClientRect().left;

                        //var w0 = leftElem.getBoundingClientRect().width;
                        if (/px/.test(leftElem.style.width)) console.error('PANEL ' + leftElem.id + ' width must be expressed in % and not px');
                        var w0 = parseFloat(leftElem.style.width.replace(/%/, ''));
                        var w1 = x - left;
                        var w1pct = (w1 * 100) / ww;

                        leftElem.style.width = w1pct + '%';
                        var rw = parseFloat(rightElem.style.width.replace(/%/, ''));
                        rightElem.style.width = (rw + (w0 - w1pct)) + '%';

                        _paneldragger = null;
                        doRepositionDividers();
                    }
                    else if (/\bdragger-v\b/.test(_paneldragger.classList)) {
                        var topElem = document.getElementById(_paneldragger.getAttribute('data-elem'));
                        var bottomElem = topElem.nextElementSibling;

                        _paneldragger.setAttribute('data-dragging', 0);

                        var wh = window.innerHeight;
                        var y0 = _paneldragger.getAttribute('data-startdrag');
                        var y = _paneldragger.getBoundingClientRect().top;
                        var top = topElem.getBoundingClientRect().top;

                        if (/px/.test(topElem.style.height)) console.error('PANEL ' + topElem.id + ' height must be expressed in % and not px');
                        var h0 = parseFloat(topElem.style.height.replace(/%/, ''));
                        var h1 = y - top;
                        var h1pct = (h1 * 100) / wh;

                        topElem.style.height = h1pct + '%';
                        var bh = parseFloat(bottomElem.style.height.replace(/%/, ''));
                        bottomElem.style.height = (bh + (h0 - h1pct)) + '%';

                        _paneldragger = null;
                        doRepositionDividers();
                    }
                }

            });
        }
    };
};


window.addEventListener('load', function () {
    new MFPanels().init();
});

About

License

Latest Release

Version 1.122024-05-08