Hybrid View

  1. #1
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Answers
    4
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default Unanswered: [Ext.ux.Lightbox] use with html

    Unanswered: [Ext.ux.Lightbox] use with html


    Hi,

    the lightbox is for usage with images only.
    Why not supporting HTML as well? From a short look there has to be an alternative template with iframe, additionally sizes.

    Something like
    Ext.ux.Lightbox.register(elements, group, isHTML, width, height)

    is it planned anyway?
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5

  2. #2
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Answers
    4
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default


    on second look i saw that there already is an iframe which could be used (shim) - i think this one is supposed for usage of HTML? It's not used atm.
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5

  3. #3
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Answers
    4
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default


    i did it, not a perfect solution but basically it works.
    Of course there is some double code, as original always handle images.

    For those who want to test it i post the complete lightbox.js

    i register html with :
    Ext.ux.Lightbox.registerUrl("a.typo3-csh-link", 600, 400);


    Code:
    Ext.ns('Ext.ux');
    
    Ext.ux.Lightbox = (function(){
        var els = {},
            images = [],
            urls = [],
            activeImage,
            activeUrl,
            initialized = false,
            selectors = [];
    
        return {
            overlayOpacity: 0.85,
            animate: true,
            resizeSpeed: 8,
            borderSize: 10,
            labelImage: "Image",
            labelOf: "of",
    
            init: function() {
                this.resizeDuration = this.animate ? ((11 - this.resizeSpeed) * 0.15) : 0;
                this.overlayDuration = this.animate ? 0.2 : 0;
    
                if(!initialized) {
                    Ext.apply(this, Ext.util.Observable.prototype);
                    Ext.util.Observable.constructor.call(this);
                    this.addEvents('open', 'close');
                    this.initMarkup();
                    this.initEvents();
                    initialized = true;
                }
            },
    
            initMarkup: function() {
                
                els.overlay = Ext.DomHelper.append(document.body, {
                    id: 'ux-lightbox-overlay'
                }, true);
                
                var lightboxTpl = new Ext.Template(this.getTemplate());
                els.lightbox = lightboxTpl.append(document.body, {}, true);
    
                els.shim = Ext.DomHelper.append(Ext.fly('ux-lightbox-imageContainer'), {
                    tag: 'iframe',
                    id: 'ux-lightbox-shim'
                }, true);
                
                var ids =
                    ['outerImageContainer', 'imageContainer', 'image', 'hoverNav', 'navPrev', 'navNext', 'loading', 'loadingLink',
                    'outerDataContainer', 'dataContainer', 'data', 'details', 'caption', 'imageNumber', 'bottomNav', 'navClose'];
    
                Ext.each(ids, function(id){
                    els[id] = Ext.get('ux-lightbox-' + id);
                });
    
                Ext.each([els.overlay, els.lightbox, els.shim], function(el){
                    el.setVisibilityMode(Ext.Element.DISPLAY)
                    el.hide();
                });
    
                var size = (this.animate ? 250 : 1) + 'px';
                els.outerImageContainer.setStyle({
                    width: size,
                    height: size
                });
            },
    
            getTemplate : function() {
                return [
                    '<div id="ux-lightbox">',
                        '<div id="ux-lightbox-outerImageContainer">',
                            '<div id="ux-lightbox-imageContainer">',
                                '<img id="ux-lightbox-image">',
                                '<div id="ux-lightbox-hoverNav">',
                                    '<a href="#" id="ux-lightbox-navPrev"></a>',
                                    '<a href="#" id="ux-lightbox-navNext"></a>',
                                '</div>',
                                '<div id="ux-lightbox-loading">',
                                    '<a id="ux-lightbox-loadingLink"></a>',
                                '</div>',
                            '</div>',
                        '</div>',
                        '<div id="ux-lightbox-outerDataContainer">',
                            '<div id="ux-lightbox-dataContainer">',
                                '<div id="ux-lightbox-data">',
                                    '<div id="ux-lightbox-details">',
                                        '<span id="ux-lightbox-caption"></span>',
                                        '<span id="ux-lightbox-imageNumber"></span>',
                                    '</div>',
                                    '<div id="ux-lightbox-bottomNav">',
                                        '<a href="#" id="ux-lightbox-navClose"></a>',
                                    '</div>',
                                '</div>',
                            '</div>',
                        '</div>',
                    '</div>'
                ];
            },
    
            initEvents: function() {
                var close = function(ev) {
                    ev.preventDefault();
                    this.close();
                };
    
                els.overlay.on('click', close, this);
                els.loadingLink.on('click', close, this);
                els.navClose.on('click', close, this);
    
                els.lightbox.on('click', function(ev) {
                    if(ev.getTarget().id == 'ux-lightbox') {
                        this.close();
                    }
                }, this);
    
                els.navPrev.on('click', function(ev) {
                    ev.preventDefault();
                    this.setImage(activeImage - 1);
                }, this);
    
                els.navNext.on('click', function(ev) {
                    ev.preventDefault();
                    this.setImage(activeImage + 1);
                }, this);
            },
    
            register: function(sel, group) {
                if(selectors.indexOf(sel) === -1) {
                    selectors.push(sel);
    
                    Ext.fly(document).on('click', function(ev){
                        var target = ev.getTarget(sel);
    
                        if (target) {
                            ev.preventDefault();
                            this.open(target, sel, group);
                        }
                    }, this);
                }
            },
    
            registerUrl: function(sel, width, height) {
                if(selectors.indexOf(sel) === -1) {
                    selectors.push(sel);
    
                    Ext.fly(document).on('click', function(ev){
                        var target = ev.getTarget(sel);
    
                        if (target) {
                            ev.preventDefault();
                            this.openUrl(target, width, height);
                        }
                    }, this);
                }
            },
    
            open: function(image, sel, group) {
                group = group || false;
                this.setViewSize();
                els.overlay.fadeIn({
                    duration: this.overlayDuration,
                    endOpacity: this.overlayOpacity,
                    callback: function() {
                        images = [];
    
                        var index = 0;
                        if(!group) {
                            images.push([image.href, image.title]);
                        }
                        else {
                            var setItems = Ext.query(sel);
                            Ext.each(setItems, function(item) {
                                if(item.href) {
                                    images.push([item.href, item.title]);
                                }
                            });
    
                            while (images[index][0] != image.href) {
                                index++;
                            }
                        }
    
                        // calculate top and left offset for the lightbox
                        var pageScroll = Ext.fly(document).getScroll();
    
                        var lightboxTop = pageScroll.top + (Ext.lib.Dom.getViewportHeight() / 10);
                        var lightboxLeft = pageScroll.left;
                        els.lightbox.setStyle({
                            top: lightboxTop + 'px',
                            left: lightboxLeft + 'px'
                        }).show();
    
                        this.setImage(index);
                        
                        this.fireEvent('open', images[index]);                                        
                    },
                    scope: this
                });
            },
            
            openUrl: function(url, fWidth, fHeight) {
                els.shim.dom.src = '';
                this.setViewSize();
                els.overlay.fadeIn({
                    duration: this.overlayDuration,
                    endOpacity: this.overlayOpacity,
                    callback: function() {
                        urls = [];
    
                        var index = 0;
                        urls.push([url.href, url.title]);
                        
    
                        // calculate top and left offset for the lightbox
                        var pageScroll = Ext.fly(document).getScroll();
    
                        var lightboxTop = pageScroll.top + (Ext.lib.Dom.getViewportHeight() / 10);
                        var lightboxLeft = pageScroll.left;
                        els.lightbox.setStyle({
                            top: lightboxTop + 'px',
                            left: lightboxLeft + 'px'
                        }).show();
                        els.shim.setStyle({
    						width: fWidth + 'px',
                            height: fHeight + 'px'                    
                        })
                        this.setUrl(index, fWidth, fHeight);
                        
                        this.fireEvent('open', urls[index]);                                        
                    },
                    scope: this
                });
            },
            
            setViewSize: function(){
                var viewSize = this.getViewSize();
                els.overlay.setStyle({
                    width: viewSize[0] + 'px',
                    height: viewSize[1] + 'px'
                });
                els.shim.setStyle({
                    width: viewSize[0] + 'px',
                    height: viewSize[1] + 'px'
                }).show();
            },
    
            setImage: function(index){
                activeImage = index;
                          
                this.disableKeyNav();            
                if (this.animate) {
                    els.loading.show();
                }
    
                els.image.hide();
                els.hoverNav.hide();
                els.navPrev.hide();
                els.navNext.hide();
                els.dataContainer.setOpacity(0.0001);
                els.imageNumber.hide();
    
                var preload = new Image();
                preload.onload = (function(){
                    els.image.dom.src = images[activeImage][0];
                    this.resizeImage(preload.width, preload.height);
                }).createDelegate(this);
                preload.src = images[activeImage][0];
            },
    
            setUrl: function(index, fWidth, fHeight){
                activeUrl = index;
                          
                this.disableKeyNav();            
                if (this.animate) {
                    els.loading.show();
                }
    
                els.image.hide();
                els.hoverNav.hide();
                els.navPrev.hide();
                els.navNext.hide();
                els.dataContainer.setOpacity(0.0001);
                els.imageNumber.hide();
    
                els.shim.dom.src = urls[activeUrl][0];
                
                var wCur = els.outerImageContainer.getWidth();
                var hCur = els.outerImageContainer.getHeight();
    
                var wNew = fWidth;
                var hNew = fHeight;
    
                var wDiff = wCur - wNew;
                var hDiff = hCur - hNew;
    
                var queueLength = 0;
    
                if (hDiff != 0 || wDiff != 0) {
                    els.outerImageContainer.syncFx()
                        .shift({
                            height: hNew,
                            duration: this.resizeDuration
                        })
                        .shift({
                            width: wNew,
                            duration: this.resizeDuration
                        });
                    queueLength++;
                }
    
                var timeout = 0;
                if ((hDiff == 0) && (wDiff == 0)) {
                    timeout = (Ext.isIE) ? 250 : 100;
                }
    
                (function(){
                    els.hoverNav.setWidth(els.imageContainer.getWidth() + 'px');
    
                    els.navPrev.setHeight(fHeight + 'px');
                    els.navNext.setHeight(fHeight + 'px');
    
                    els.outerDataContainer.setWidth(wNew + 'px');
                    els.dataContainer.setOpacity(100);
    
                }).createDelegate(this).defer((this.resizeDuration*1000) + timeout);
                
            },
    
            resizeImage: function(w, h, urlmode){
                var wCur = els.outerImageContainer.getWidth();
                var hCur = els.outerImageContainer.getHeight();
    
                var wNew = (w + this.borderSize * 2);
                var hNew = (h + this.borderSize * 2);
    
                var wDiff = wCur - wNew;
                var hDiff = hCur - hNew;
    
                var queueLength = 0;
    
                if (hDiff != 0 || wDiff != 0) {
                    els.outerImageContainer.syncFx()
                        .shift({
                            height: hNew,
                            duration: this.resizeDuration
                        })
                        .shift({
                            width: wNew,
                            duration: this.resizeDuration
                        });
                    queueLength++;
                }
    
                var timeout = 0;
                if ((hDiff == 0) && (wDiff == 0)) {
                    timeout = (Ext.isIE) ? 250 : 100;
                }
    
                (function(){
                    els.hoverNav.setWidth(els.imageContainer.getWidth() + 'px');
    
                    els.navPrev.setHeight(h + 'px');
                    els.navNext.setHeight(h + 'px');
    
                    els.outerDataContainer.setWidth(wNew + 'px');
    
                    this.showImage();
                }).createDelegate(this).defer((this.resizeDuration*1000) + timeout);
            },
    
            showImage: function(){
                els.loading.hide();
                els.image.fadeIn({
                    duration: this.resizeDuration,
                    scope: this,
                    callback: function(){
                        this.updateDetails();
                    }
                });
                this.preloadImages();
            },
    
            updateDetails: function(){
                els.details.setWidth((els.data.getWidth(true) - els.navClose.getWidth() - 10) + 'px');
                
                els.caption.update(images[activeImage][1]);
    
                els.caption.show();
                if (images.length > 1) {
                    els.imageNumber.update(this.labelImage + ' ' + (activeImage + 1) + ' ' + this.labelOf + '  ' + images.length);
                    els.imageNumber.show();
                }
    
                els.dataContainer.syncFx()
                    .slideIn('t', {
                        duration: this.resizeDuration/2
                    })
                    .fadeIn({
                        duration: this.resizeDuration/2,
                        scope: this,
                        callback: function() {
                            var viewSize = this.getViewSize();
                            els.overlay.setHeight(viewSize[1] + 'px');
                            this.updateNav();
                        }
                    })
            },
    
            updateNav: function(){
                this.enableKeyNav();
    
                els.hoverNav.show();
    
                // if not first image in set, display prev image button
                if (activeImage > 0)
                    els.navPrev.show();
    
                // if not last image in set, display next image button
                if (activeImage < (images.length - 1))
                    els.navNext.show();
            },
    
            enableKeyNav: function() {
                Ext.fly(document).on('keydown', this.keyNavAction, this);
            },
    
            disableKeyNav: function() {
                Ext.fly(document).un('keydown', this.keyNavAction, this);
            },
    
            keyNavAction: function(ev) {
                var keyCode = ev.getKey();
    
                if (
                    keyCode == 88 || // x
                    keyCode == 67 || // c
                    keyCode == 27
                ) {
                    this.close();
                }
                else if (keyCode == 80 || keyCode == 37){ // display previous image
                    if (activeImage != 0){
                        this.setImage(activeImage - 1);
                    }
                }
                else if (keyCode == 78 || keyCode == 39){ // display next image
                    if (activeImage != (images.length - 1)){
                        this.setImage(activeImage + 1);
                    }
                }
            },
    
            preloadImages: function(){
                var next, prev;
                if (images.length > activeImage + 1) {
                    next = new Image();
                    next.src = images[activeImage + 1][0];
                }
                if (activeImage > 0) {
                    prev = new Image();
                    prev.src = images[activeImage - 1][0];
                }
            },
    
            close: function(){
                this.disableKeyNav();
                els.lightbox.hide();
                els.overlay.fadeOut({
                    duration: this.overlayDuration
                });
                els.shim.hide();
                this.fireEvent('close', activeImage);
            },
    
            getViewSize: function() {
                return [Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true)];
            }
        }
    })();
    
    Ext.onReady(Ext.ux.Lightbox.init, Ext.ux.Lightbox);
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5

  4. #4
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Answers
    4
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default


    i did a small live example
    http://dev.sk-typo3.de/ext/lightbox.html
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5

  5. #5
    Sencha User
    Join Date
    Feb 2008
    Posts
    21
    Vote Rating
    0
    omegafox is on a distinguished road

      0  

    Default


    That is so great! I was looking for it for few months. It works great in firefox but it dont work with IE8 that it didnt show anything in lightbox.

  6. #6
    Sencha User steffenk's Avatar
    Join Date
    Jul 2007
    Location
    Haan, Germany
    Posts
    2,664
    Answers
    4
    Vote Rating
    7
    steffenk has a spectacular aura about steffenk has a spectacular aura about steffenk has a spectacular aura about

      0  

    Default


    i have to look why. I jslinted, but this is not the problem. The iframe is loaded (even links are there if you hover) but it's in the back.
    vg Steffen
    --------------------------------------
    Release Manager of TYPO3 4.5