PDA

View Full Version : [Ext.ux.Lightbox] use with html



steffenk
4 Jul 2009, 2:37 PM
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?

steffenk
5 Jul 2009, 1:48 AM
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.

steffenk
5 Jul 2009, 10:15 AM
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);




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);

steffenk
5 Jul 2009, 3:11 PM
i did a small live example
http://dev.sk-typo3.de/ext/lightbox.html

omegafox
14 Jul 2009, 1:27 PM
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.

steffenk
15 Jul 2009, 7:25 AM
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.

omegafox
16 Jul 2009, 5:51 AM
oh yeah. you are right. Interesting ......just wondering. is it fixable?

steffenk
16 Jul 2009, 6:05 AM
i'm not a fan of IE at all - and i didn't get the console to run with 3.0, so stay tuned and patient, has to be fixed anyway.

Foggy
24 Jul 2009, 1:23 AM
Great, thanks man...

orkunbaba
30 Jul 2009, 12:27 AM
its realy good if fixed ie8 bug.

steffenk
1 Aug 2009, 1:13 AM
i fixed the IE issue - it's pure css.

I also added possibility to call the lightbox directly with a text ore some html.

See the demo: http://dev.sk-typo3.de/ext/lightbox.html

miss4813
3 Aug 2009, 10:28 PM
不错,这个玩意正好用上。:)

omegafox
4 Aug 2009, 8:55 AM
YAY!!!! It is working great with IE8. THANK YOU SO MUCH!!! I really do. :D

Stju
14 May 2010, 9:04 PM
Hummm. does not work with 3.2 ...

phyton
25 Jul 2010, 3:14 AM
try this http://code.atmaworks.com/extbox/

has support iframe and inline code

waschtl
9 Aug 2010, 11:24 AM
Hi,
I like this lightbox. I'm not verry familiar with extjs and just play a little bit around. Today I tried to open a lightbox and show a extjs.FormPanel. So far this works, but when i render my form inside of the lightbox I can't use any of the implemented buttons - no handler gets called. If i try to render the form to `document.body` all buttons work normal. Her is a little bit of my code:

In the HTML-code I do as in the Demo and place a hidden div:


<div id='lightbox' style="display: none">
<b>Motor editieren</b>

</div>
I don't use a link to call the lightbox - It's opend by a menu


function showLightbox(title, width, height){
Ext.ux.extbox.open(Ext.fly('inline'), 'inline', false, {
href: '#lightbox',
title: title,
inline: true,
scale: false,
animate: true,
width: width,
height: height,
close: '×',
hideInfo: 'auto'
});
};
render the form and show the lightbox:


function editEngine(){
debug('Motor editieren', 'Formular rendern');
mdb.forms.editEngine = new Ext.FormPanel({
labelWidth: 75,
url: 'edit_engine_data',
frame: true,
title: 'Daten eingeben',
bodyStyle: 'padding:5px 5px 0',
width: 350,
defaults: {
width: 230
},
defaultType: 'textfield',

items: [{
fieldLabel: 'Name',
name: 'name',
allowBlank: false
}, {
fieldLabel: 'Bezeichnung',
name: 'description'
}, {
fieldLabel: 'Serialnummer',
name: 'serailNr'
}, {
fieldLabel: 'Leistung',
name: 'wattage'
}, {
fieldLabel: 'Spannung',
name: 'voltage'
}],

buttons: [{
text: 'Save',
handler: function(){console.log('saveButton')}
}, {
text: 'Cancel',
handler: function(){console.log('cancelButton')}
}]
});
mdb.forms.editEngine.addButton({
text: 'just close',
handler: function(){
Ext.ux.extbox.close();
}
})


mdb.forms.editEngine.render(Ext.fly('lightbox'));
showLightbox('Motor Editieren', 500, 350);

// mdb.forms.editEngine.render(document.body);

}


any idea what I am doing wrong?

mcouillard
5 Oct 2010, 10:53 AM
Great plugin, phyton! Seems to work well with Ext Core 3.0 and FF. Currently debugging a few issues seen in IE8...

lakshmi
15 Mar 2011, 9:14 PM
Will you please tell me how can i call this lightbox for an enlarged view of image. Scenario is, i have a window with an image and a link. When i click the link image needs to be enlarged. My doubt is how can i call this lightbox extension to achieve my requirement. Will you please provide some code snippets to describe the calling part.

fabio.policeno
17 Aug 2012, 1:08 PM
animate: false don't work, continue with animation in interface. Any ideas?

Thank's