/* * KFBox * jQuery plugin for displaying images or AJAX content in lightbox style popup. * Supports smart paging with page numbers. Inspired by Thickbox 2.0 by Cody Lindley. * * Copyright (c) 2008 Karel Fučík * Licensed under the MIT License (http://www.opensource.org/licenses/mit-license.php) */ (function($){ $.fn.kfBox = function(options) { new kfBox(this, options); return this; }; var kfBox = function($elements, options) { this.$elements = $elements; this.options = $.extend({ hashPrefix: 'kfbox-', minWidth: 665, maxWidth: 850, topOffset: 40, pageSpan: 3, pageLeaders: ' … ', historyLoadCallback: null, afterShowCallback: null, langCode: null, langs: { cs: { close: "Zavřít", prev: "předchozí", next: "další" }, en: { close: "Close", prev: "previous", next: "next" }, de: { close: "Zumachen", prev: "vorige", next: "folgend" }, es: { close: "Vaer", prev: "previo", next: "siguiente" }, fr: { close: "Fermer", prev: "précédant", next: "suivant" }, it: { close: "Chiudere", prev: "previo", next: " veniente" }, ru: { close: "закрыть", prev: "предшествующий", next: "последующий" } }, htmlTemplate: "

" }, options); this.langCode = this.options.langCode || $('html').attr('xml:lang') || 'cs'; this.isOpen = false; this.oldHash = ''; var that = this; this.$elements.bind('click', function(event) { that.oldHash = window.location.hash.replace('#', ''); if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(that.getHash(this)); else that.showByHash(that.getHash(this)); return false; }); }; kfBox.prototype = new function() { this.getHash = function(element) { return this.options.hashPrefix + (this.$elements.index(element) + 1); }; this.showByHash = function(hash) { if(hash.indexOf(this.options.hashPrefix) !== 0){ this.hideBox(); return false; } this.activeIndex = parseInt(hash.replace(this.options.hashPrefix, '')) - 1; this.$activeLink = $(this.$elements[this.activeIndex]); this.renderBox(); this.initGroup(this.$activeLink); return true; }; this.renderBox = function() { if(!this.isOpen) { this.showOverlay(); var $htmlTemplate = $(this.options.htmlTemplate); $("body").append($htmlTemplate); $("#kfb-prev").html(this.options.langs[this.langCode]["prev"]); $("#kfb-next").html(this.options.langs[this.langCode]["next"]); $("#kfb-close-btn").html(this.options.langs[this.langCode]["close"]); $("#kfb-image-anchor").attr('title', this.options.langs[this.langCode]["close"]); $("#kfb-close-btn").bind('click', {kfBox: this} ,this.closeBox); this.positionBox(this.options.minWidth); this.isOpen = true; } }; this.closeBox = function(event) { that = event.data.kfBox; if(that.isOpen) { if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(that.oldHash); return that.hideBox(); } }; this.hideBox = function() { $('#kfb-window, #kfb-overlay, #kfb-iframe').remove(); $(document).unbind('keyup'); this.isOpen = false; return false; }; this.initGroup = function() { var that = this; var title = this.$activeLink.attr('title'); /* Generate paging... */ var pagesCount = this.$elements.size(); var htmlPages = ''; var pageSpan = this.options.pageSpan; var startSpan = this.activeIndex - pageSpan; var endSpan = this.activeIndex + pageSpan + 1; if(startSpan <= 0) { startSpan = 0; endSpan = 2 * pageSpan + 2; if(endSpan > pagesCount) endSpan = pagesCount - 1; } if(endSpan >= pagesCount - 1) { startSpan = pagesCount - 2 - 2 * pageSpan; if(startSpan < 0) startSpan = 0; endSpan = pagesCount - 1; } var factoryPageLink = function(i) { var active = (i == that.activeIndex) ? ' class="active" ' : ''; return ' ' + (i + 1) + ' '; }; this.$elements.slice(startSpan, endSpan).each(function(i) { htmlPages += factoryPageLink.call(this, i + startSpan); }).end(); if(startSpan > 1) htmlPages = this.options.pageLeaders + htmlPages; if(startSpan > 0) this.$elements.eq(0).each(function(i){ htmlPages = factoryPageLink.call(this, 0) + htmlPages; }).end(); if(endSpan <= pagesCount - 2) htmlPages += this.options.pageLeaders; if(endSpan <= pagesCount - 1) this.$elements.eq(pagesCount - 1).each(function(i){ htmlPages += factoryPageLink.call(this, pagesCount - 1); }).end(); $("#kfb-page-list").empty().append(htmlPages); $("#kfb-prev").unbind('click').bind('click', function(){ that.$elements.eq(that.activeIndex - 1).trigger('click').end(); return false; }); $("#kfb-next").unbind('click').bind('click', function(){ that.$elements.eq(that.activeIndex + 1).trigger('click').end(); return false; }); $("#kfb-prev, #kfb-next, #kfb-page-list").removeClass('hidden'); if(this.activeIndex == 0) $("#kfb-prev").addClass('hidden'); if(this.activeIndex == pagesCount - 1) $("#kfb-next").addClass('hidden'); if(pagesCount <= 1) $("#kfb-prev, #kfb-next, #kfb-page-list").addClass('hidden'); $("#kfb-page-list a") .bind('click', function() { var hash = that.options.hashPrefix + $(this).text(); if(typeof that.options.historyLoadCallback == 'function') that.options.historyLoadCallback(hash); else that.showByHash(hash); return false; }); $(document).unbind('keyup').bind('keyup', function(e) { switch(e.keyCode) { case 27: $("#kfb-close-btn").trigger('click'); break; case 37: $("#kfb-prev:visible").trigger('click'); break; case 39: $("#kfb-next:visible").trigger('click'); break; } }); this.preloadContent(this.$activeLink.attr('href')); }; this.preloadContent = function(href) { var regexp = /jpg|jpeg|png|gif/; if(href.toLowerCase().search(regexp) !== -1) this.preloadImage(href); else this.preloadHtml(href); }; this.preloadImage = function(href) { var that = this; $('#kfb-caption, #kfb-desc, #kfb-image-anchor').removeClass('hidden'); $("#kfb-content").addClass('hidden'); var $imageAnchor = $('#kfb-image-anchor'); $imageAnchor .height($imageAnchor[0].offsetHeight + "px") .find('img').remove().end(); $('#kfb-content').empty(); var imgPreloader = $(document.createElement('img')) .bind('load', function(e) { this.onload = null; var imageWidth = this.width; var imageHeight = this.height; var $img = $('img', that.$activeLink); var caption = $img.attr('alt') || that.$activeLink.attr('title'); var desc = $img.attr('title'); var longdesc = $img.attr('longdesc'); var enhdesc = []; if(desc) enhdesc.push(desc); if(longdesc) enhdesc.push('' + longdesc + ''); enhdesc = enhdesc.join(', '); if(caption) $("#kfb-caption").removeClass("hidden").html(caption); else $("#kfb-caption").addClass("hidden").empty(); if(enhdesc) $("#kfb-desc").removeClass("hidden").html(enhdesc); else $("#kfb-desc").addClass("hidden").empty(); $('#kfb-image-anchor').removeClass('hidden'); var boxWidth = imageWidth; if(boxWidth < that.options.minWidth) boxWidth = that.options.minWidth; that.positionBox(boxWidth); this.alt = caption; if(desc) this.title = desc; $('#kfb-image-anchor').height("auto").empty().append(this).bind('click', function() { that.hideBox(); return false; } ); $("#kfb-window").css({display:"block"}); if(typeof that.options.afterShowCallback == 'function') that.options.afterShowCallback(that.$activeLink[0]); }) .attr('src', href); }; this.preloadHtml = function(href) { var that = this; $("#kfb-content").removeClass('hidden').addClass('loader'); $('#kfb-caption, #kfb-desc, #kfb-image-anchor').addClass('hidden'); var $imageAnchor = $('#kfb-image-anchor').find('img').remove(); boxWidth = that.options.maxWidth; $("#kfb-content").load(href, null, function() { $("#kfb-content").removeClass('loader'); if(typeof that.options.afterShowCallback == 'function') that.options.afterShowCallback(that.$activeLink[0]); }); }; this.positionBox = function(boxWidth) { var scrollTop = $(window).scrollTop(); var windowWidth = boxWidth + parseInt($('#kfb-image-anchor').css('padding-left')) * 2; $("#kfb-window").css({marginLeft: '-' + parseInt(windowWidth / 2) + 'px', width: windowWidth + 'px', top: (scrollTop + this.options.topOffset) + 'px'}); }; this.showOverlay = function() { if($("#kfb-iframe").size() == 0) { $("body").append("
"); $("#kfb-overlay").bind('click', {kfBox: this}, this.closeBox); var documentHeight = $(document).height(); var windowHeight = $(window).height(); var maxHeight = documentHeight > windowHeight ? documentHeight : windowHeight; $("#kfb-overlay, #kfb-iframe").css("height", maxHeight); } }; }; $.kfBox = kfBox; })(jQuery)