/** * QSF Slide Application * @uses JQuery, YAHOO.widget.Paginator **/ var App_Slide = qs.create(); App_Slide.prototype = { __instances: [], _timer: null, _arrowTimer: null, _mouseTimer: null, _mouseOverStatus: null, _animated: false, _buttons: [{name: 'prev', title: 'Prev'}, {name: 'play', title: 'Play', arguments: [0]}, {name: 'pause', title: 'Pause'}, {name: 'next', title: 'Next'}], arrowsSize: [24, 24], // [width, height] _paginatorTemplatePlaceholders: ['{FirstPageLink}', '{PreviousPageLink}', '{PageLinks}', '{NextPageLink}', '{LastPageLink}'], paginator: null, container: null, itemContainer: null, buttonsContainer: null, index: null, slides: null, idItem: null, status: null, autostart: true, direction: 'right', interval: 5000, effect: 'slide', effectDuration: 500, showArrows: true, enableButtons: true, enablePaginator: true, pageLinkWidth: 24, paginatorOptions: { firstPageLinkLabel: '«', previousPageLinkLabel: '‹', nextPageLinkLabel: '›', lastPageLinkLabel: '» ', rowsPerPage : 1 }, init: function (options) { new App_Slide(options); }, initialize: function (options) { this.setOptions(options); if (!this.slides.length) { return false; } App_Slide.prototype.__instances[this.idItem] = this; var obj = this; // prepare HTML this.container.onmouseover = function (event) { obj.itemOnMouseOver(event); } this.container.onmouseout = function (event) { obj.itemOnMouseOut(event); } if (this.showArrows) { this.nextButton = document.createElement('div'); this.nextButton.className = 'slide_next_button ie_png_bg'; this.nextButton.style.display = 'none'; this.nextButton.style.marginTop = Math.ceil((this.height - this.arrowsSize[1])/2) + 'px'; this.nextButton.style.marginLeft = (this.width - this.arrowsSize[0]) + 'px'; this.nextButton.onclick = function() { obj.next(); } this.container.appendChild(this.nextButton); this.prevButton = document.createElement('div'); this.prevButton.className = 'slide_prev_button ie_png_bg'; this.prevButton.style.display = 'none'; this.prevButton.style.marginTop = Math.ceil((this.height - this.arrowsSize[1])/2) + 'px'; this.prevButton.style.marginLeft = '0px'; this.prevButton.onclick = function() { obj.prev(); } this.container.appendChild(this.prevButton); } this.itemContainer = document.createElement('div'); this.itemContainer.className = 'slide_items_container'; this.itemContainer.style.width = this.width + 'px'; this.itemContainer.style.height = this.height + 'px'; this.container.appendChild(this.itemContainer); if (this.enableButtons || this.enablePaginator) { this.toolbarContainer = document.getElementById('slides-toolbar-container-' + this.idItem); if (!this.toolbarContainer) { this.toolbarContainer = document.createElement('div'); this.toolbarContainer.id = 'slides-toolbar-container-' + this.idItem; if (this.container.nextSibling) { this.container.parentNode.insertBefore(this.toolbarContainer, this.container.nextSibling); } else { this.container.parentNode.appendChild(this.toolbarContainer); } } this.toolbarContainer.className = 'slide_toolbar_container'; this.paginatorContainer = document.createElement('div'); this.paginatorContainer.className = 'slide_paginator'; this.paginatorContainer.id = 'slide-toolbar-' + this.idItem; this.toolbarContainer.appendChild(this.paginatorContainer); } if (this.enableButtons) { this.buttonsContainer = document.createElement('div'); this.buttonsContainer.className = 'slide_player'; for (var i = this._buttons.length -1; i >=0 ; i--) { var button = this._buttons[i]; var a = document.createElement('a'); a.className = button.name; a.title = button.title; a.href = '#'; var functionCode = 'var obj = App_Slide.prototype.getInstance(\'' + this.idItem + '\'); ' + 'obj.' + button.name; if (typeof button.arguments != 'undefined' && button.arguments.length) { functionCode += '.apply(obj, ' + json_encode(button.arguments) + ');'; } else { functionCode += '();'; } functionCode += ' return false;'; a.setAttribute('onclick', functionCode); this.buttonsContainer.appendChild(a); } this.toolbarContainer.appendChild(this.buttonsContainer); } if (this.toolbarContainer) { var clear = document.createElement('div'); clear.className = 'clear'; this.toolbarContainer.appendChild(clear); } // end of prepare HTML this.showToolbar(); $('.slide_preload', this.container).fadeOut(250); $('.slide_preload', this.container).remove(); for (var i = 0; i < this.slides.length; i++) { this.slides[i].showTime = false; this.slides[i]._animated = true; this.setVisible(false, i); } this.slides[0].showTime = new Date().getTime(); if (this.autostart) { this.play(0); } else { this.preload(0); } }, setOptions: function (options) { if (typeof options == 'object') { for (var field in options) { var value = options[field]; if (typeof value == 'string' && !value.length) { continue; } switch (field) { case 'interval': this.setInterval(value); break; case 'idContainer': this.setContainer(value); break; case 'slides': if (typeof value == 'object') { this.setSlides(value) } break; case 'paginatorOptions': this.setPaginatorOptions(value); break; case 'idItem': this.setIdItem(value); break; case 'effectDuration': value = intval(value); // break intentionally omitted default: this[field] = value; } } } }, setPaginatorOption: function (name, value) { if (typeof value == 'string' && !value.length) { return false; } if (name == 'linkWidth' && intval(value)) { this.pageLinkWidth = intval(value); return false; } this.paginatorOptions[name] = value; }, setPaginatorOptions: function (options) { for (var i in options) { this.setPaginatorOption(i, options[i]); } }, isVisible: function (index) { if (typeof index == 'undefined') { index = this.index; } if (typeof this.slides[index] != 'undefined') { return this.slides[index].visible; } return false; }, setVisible: function (visible, index) { if (typeof index == 'undefined') { index = this.index; } if (typeof this.slides[index] != 'undefined') { this.slides[index].visible = visible; } return false; }, isPreloaded: function (index) { if (typeof index == 'undefined') { index = this.index; } if (typeof this.slides[index] != 'undefined' && typeof this.slides[index].containerObj != 'undefined') { return true; } return false; }, getInstance: function(id) { if (typeof App_Slide.prototype.__instances[id] != 'undefined') { return App_Slide.prototype.__instances[id]; } return false; }, setInterval: function (interval) { interval = parseFloat(interval); if (!isNaN(interval) && interval != 0) { this.interval = interval * 1000; return true; } alert('App_Slide: time interval is wrong!'); return false; }, setIdItem: function (id) { id = parseInt(id); if (!isNaN(id) && id != 0) { this.idItem = id; this.setContainer('slides-container-' + id); return true; } alert('App_Slide: idItem is wrong!'); return false; }, setContainer: function(id) { this.container = document.getElementById(id); if (this.container) { return true; } this.container = null; alert('App_Slide: slides container is wrong!'); return false; }, prev: function () { if (!this._animated) { return false; } this.stop(); var direction = this.direction; this.direction = 'left'; this.initNextShowTime(0); this.preload(); this.direction = direction; }, play: function (interval) { this._mouseOverStatus = null; this.log('play'); this.status = 'play'; this._mouseOverStatus = 'play'; if (typeof interval != 'undefined') { this.initNextShowTime(interval); } else { this.initNextShowTime(interval); } this.preload(); this.startTimer(); this.hideButton('play'); this.showButton('pause'); }, next: function () { if (!this._animated) { return false; } this.stop(); var direction = this.direction; this.direction = 'right'; this.initNextShowTime(0); this.preload(); this.direction = direction; }, pause: function () { this.stop(); this.showButton('play'); this.hideButton('pause'); }, hideButton: function (name) { $('a.' + name, this.buttonsContainer).hide(); }, showButton: function (name) { $('a.' + name, this.buttonsContainer).show(); }, setSlides: function(slides) { if (typeof slides == 'object') { this.slides = slides return true; } alert('App_Slide: slides are not object!'); return false; }, startTimer: function () { if (this._timer != null) { clearTimeout(this._timer); this._timer = null; } this._timer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').preload()', this.interval); return true; }, stopTimer: function () { if (this._timer != null) { clearTimeout(this._timer); } this._timer = null; if (null != this._mouseTimer) { clearTimeout(this._mouseTimer); this._mouseTimer = null; } }, stop: function () { this.status = 'stop'; this._mouseOverStatus = 'stop'; this.stopTimer(); return true; }, showBigArrows: function () { if (this.showArrows) { $(this.prevButton).show(); $(this.nextButton).show(); } this.showToolbar(); }, hideBigArrows: function () { if (this.showArrows) { $(this.prevButton).hide(); $(this.nextButton).hide(); } this.hideToolbar(); }, itemOnMouseOver: function (event) { if (null != this._arrowTimer) { clearTimeout(this._arrowTimer); this._arrowTimer = null; } this.showBigArrows(); if (null == this._mouseOverStatus) { this._mouseOverStatus = this.status; } if (null != this._mouseTimer) { clearTimeout(this._mouseTimer); this._mouseTimer = null; } this.stopTimer(); this.showButton('play'); this.hideButton('pause'); }, itemOnMouseOut: function (event) { this._arrowTimer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').hideBigArrows();', 50); if (this._mouseOverStatus == 'play') { this._mouseTimer = setTimeout('App_Slide.prototype.getInstance(\'' + this.idItem + '\').play();', 50); } if ('play' == this._mouseOverStatus) { this.hideButton('play'); this.showButton('pause'); } }, show: function (index) { if (typeof index == 'undefined') { index = this.index; } if (this.slides[index] == null || this.slides[index] == 'undefined') { index = 0; } var slide = this.slides[index]; var direction = -1; if ((index - this.index) >= 0) { direction = 1; if (index == this.slides.length - 1 && this.index == 0) { direction = -1; } } else { if (index == 0 && this.index == this.slides.length - 1) { direction = 1; } } this.log('direction=' + direction); if (this.index != null) { if ('slide' == this.effect) { slide.containerObj.style.left = direction * this.width + 'px'; } else { this.slides[index].containerObj.style.display = 'none'; } } slide.containerObj.style.marginLeft = 0; //$('.slide_preload', this.container).remove(); $(this.itemContainer).append(slide.containerObj); this._animated = false; slide._animated = false; var obj = this; if (this.index != null) { if ('slide' == this.effect) { this.log('animation ' + (-1 * direction * this.width) + ' ' + this.effectDuration + ' ms'); $('.slide_item:first').animate( {marginLeft:-1 * direction * this.width}, {duration: this.effectDuration} ); $('.slide_item:last').animate( {marginLeft:-1 * direction * this.width}, { duration: this.effectDuration, complete: function () {obj.animationComplete(index, direction);} } ); } else { $(this.slides[this.index].containerObj).fadeOut(this.effectDuration); $(slide.containerObj).fadeIn( this.effectDuration, function () {obj.animationComplete(index, direction);} ); } } else { this.log('no animation'); obj.animationComplete(index, direction); } }, animationComplete: function (index, direction) { var slide = this.slides[index]; if ($('.slide_item', this.container).size() > 1) { if (direction) { $('.slide_item:last', this.container).css({left: 0, marginLeft: 0}); $('.slide_item:first', this.container).remove(); } else { $('.slide_item:first', this.container).css({left: 0, marginLeft: 0}); $('.slide_item:last', this.container).remove(); } } this._animated = true; slide.showTime = false; this.setVisible(false, this.index); // mark previous bannas as invisible this.log('show ' + this.index + '->' + index); this.index = index; // set current index this.paginatorSetPage(index + 1); this.setVisible(true); // mark current bannas as visible if (this.status == 'play') { this.initNextShowTime(); this.preload(); this.startTimer(); } else { this.log('status = ' + this.status); } }, hideToolbar: function () { if (!this.enablePaginator && !this.enableButtons) { return false; } return false; }, showToolbar: function () { if (!this.enablePaginator && !this.enableButtons) { return false; } if (typeof this.toolbarContainer.positionFixed == 'undefined') { var pos = qs.getPosition(this.container); var style = { visibility: 'visible', top : pos.y + (this.height - this.toolbarContainer.offsetHeight + 1) + 'px' }; // $(this.toolbarContainer).css(style); if (this.enablePaginator) { var paginatorWidth = this.width; if (this.enableButtons) { paginatorWidth -= this.buttonsContainer.offsetWidth; } // $(this.paginatorContainer).css({width: paginatorWidth + 'px'}); this.paginatorOptions.containers = 'slide-toolbar-' + this.idItem; this.paginatorOptions.totalRecords = this.slides.length; this.paginatorOptions.totalRecords = this.slides.length; var additionalPages = 0; if (typeof this.paginatorOptions.pageLinks == 'undefined') { if (typeof this.paginatorOptions.template == 'string' && this.paginatorOptions.template.length) { for (var i = 0; i < this._paginatorTemplatePlaceholders.length; i++) { var placeholder = this._paginatorTemplatePlaceholders[i]; if (placeholder == '{pageLinks}') { continue; } if (-1 != this.paginatorOptions.template.indexOf(placeholder)) { additionalPages++; } } } else { additionalPages = 4; } this.paginatorOptions.pageLinks = Math.floor(paginatorWidth / this.pageLinkWidth) - additionalPages; } this.paginator = new YAHOO.widget.Paginator(this.paginatorOptions); this.paginator.render(); var obj = this; this.paginator.subscribe('changeRequest', function(state) {obj.paginatorChangeRequest(state)}); } this.toolbarContainer.positionFixed = true; } $(this.toolbarContainer).show(); }, paginatorSetPage: function (page) { if (this.paginator) { this.paginator.setPage(page, true); } }, paginatorChangeRequest: function (state) { if (!this._animated) { return false; } var index = state.page - 1; this.initShowTime(index, 0); this.preload(index); this.paginator.setState(state); }, initShowTime: function (index, interval) { if (typeof interval == 'undefined') { interval = this.interval; } this.slides[index].showTime = new Date().getTime() + interval; }, initNextShowTime: function (interval) { this.initShowTime(this.getNextIndex(), interval); }, getNextIndex: function () { var index; if (null == this.index) { return 0; } else if ('right' == this.direction) { index = (this.slides.length == this.index + 1) ? 0 : this.index + 1; } else if ('left' == this.direction) { index = (0 == this.index) ? this.slides.length - 1 : this.index - 1; } return index; }, onabort: function (image) { return false; }, onerror: function (image) { this.next(); }, preload: function (index, onloadCallback) { if (typeof index == 'undefined') { index = this.getNextIndex(); } var obj = this; var slide = this.slides[index]; if (typeof slide.containerObj == 'undefined') { this.log('preload ' + index); slide.containerObj = document.createElement('div'); slide.containerObj.className = 'slide_item'; slide.containerObj.style.width = this.width + 'px'; slide.containerObj.style.height = this.height + 'px'; if ('image' == slide.type) { var imageObj = new Image(); imageObj.setAttribute('useMap', '#slide_map_' + slide.id); imageObj.setAttribute('alt', slide.title); imageObj.onabort = function () {obj.onabort(this)}; imageObj.onerror = function () {obj.onerror(this)}; imageObj.onload = function () { this.style.marginLeft = Math.ceil((obj.width - this.width)/2) + 'px'; this.style.marginTop = Math.ceil((obj.height - this.height)/2) + 'px'; obj.preloaded(index); } imageObj.src = slide.image; slide.containerObj.appendChild(imageObj); if (slide.hotSpotMap != 'empty') { var map = document.createElement('MAP'); map.name = 'slide_map_' + slide.id; map.id = 'slide_map_' + slide.id; // Fix IE6/IE7 area for (var key in slide.hotSpotMap) { var area = document.createElement( "AREA" ); area.shape = slide.hotSpotMap[key].shape; area.coords = slide.hotSpotMap[key].coords; area.href = slide.hotSpotMap[key].href; area.target = slide.hotSpotMap[key].target; area.alt = slide.hotSpotMap[key].alt; map.appendChild(area); } slide.containerObj.appendChild(map); } } else if ('html' == slide.type) { obj.log('preloaded ' + index); var htmlContainer = document.createElement('div'); htmlContainer.style.width = this.width + 'px'; htmlContainer.style.height = this.height + 'px'; htmlContainer.className = 'slide_html'; htmlContainer.innerHTML = slide.content; slide.containerObj.appendChild(htmlContainer); obj.preloaded(index); } } else { obj.preloaded(index); } }, preloaded: function (index) { this.log('preloaded ' + index); var now = new Date(); var slide = this.slides[index]; if (false !== slide.showTime && Math.floor(now.getTime()/1000) >= Math.floor(slide.showTime/1000)) { this.show(index); } else { this.log(slide.showTime + '\n' + now.getTime()); } }, log: function (text) { if (!this.debug || typeof console == 'undefined') { return false; } var message = 'index=' + this.index + '. [' + text + '] '; console.info(message); } }