/** * QSF Banner Application * @uses JQuery, YAHOO.widget.Paginator **/ var App_Banner = qs.create(); App_Banner.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, banners: 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_Banner(options); }, initialize: function (options) { this.setOptions(options); if (!this.banners.length) { return false; } App_Banner.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.htmlWidth) - 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 = 'banner_items_container'; this.itemContainer.style.width = (this.width + this.htmlWidth) + 'px'; this.itemContainer.style.height = this.height + 'px'; $('.banner_preload', this.container).remove(); this.container.appendChild(this.itemContainer); if (this.enableButtons || this.enablePaginator) { this.toolbarContainer = document.getElementById('banners-toolbar-container-' + this.idItem); if (!this.toolbarContainer) { this.toolbarContainer = document.createElement('div'); this.toolbarContainer.id = 'banners-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 = 'banner_toolbar_container'; this.paginatorContainer = document.createElement('div'); this.paginatorContainer.className = 'banner_paginator'; this.paginatorContainer.id = 'banner-toolbar-' + this.idItem; this.toolbarContainer.appendChild(this.paginatorContainer); } if (this.enableButtons) { this.buttonsContainer = document.createElement('div'); this.buttonsContainer.className = 'banner_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_Banner.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(); for (var i = 0; i < this.banners.length; i++) { this.banners[i].showTime = false; this.banners[i]._animated = true; this.setVisible(false, i); } this.banners[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 'banners': if (typeof value == 'object') { this.setBanners(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.banners[index] != 'undefined') { return this.banners[index].visible; } return false; }, setVisible: function (visible, index) { if (typeof index == 'undefined') { index = this.index; } if (typeof this.banners[index] != 'undefined') { this.banners[index].visible = visible; } return false; }, isPreloaded: function (index) { if (typeof index == 'undefined') { index = this.index; } if (typeof this.banners[index] != 'undefined' && typeof this.banners[index].containerObj != 'undefined') { return true; } return false; }, getInstance: function(id) { if (typeof App_Banner.prototype.__instances[id] != 'undefined') { return App_Banner.prototype.__instances[id]; } return false; }, setInterval: function (interval) { interval = parseFloat(interval); if (!isNaN(interval) && interval != 0) { this.interval = interval * 1000; return true; } alert('App_Banner: time interval is wrong!'); return false; }, setIdItem: function (id) { id = parseInt(id); if (!isNaN(id) && id != 0) { this.idItem = id; this.setContainer('banners-container-' + id); return true; } alert('App_Banner: idItem is wrong!'); return false; }, setContainer: function(id) { this.container = document.getElementById(id); if (this.container) { return true; } this.container = null; alert('App_Banner: banners 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(); }, setBanners: function(banners) { if (typeof banners == 'object') { this.banners = banners return true; } alert('App_Banner: banners are not object!'); return false; }, startTimer: function () { if (this._timer != null) { clearTimeout(this._timer); this._timer = null; } this._timer = setTimeout('App_Banner.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_Banner.prototype.getInstance(\'' + this.idItem + '\').hideBigArrows();', 50); if (this._mouseOverStatus == 'play') { this._mouseTimer = setTimeout('App_Banner.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.banners[index] == null || this.banners[index] == 'undefined') { index = 0; } var banner = this.banners[index]; var direction = -1; if ((index - this.index) >= 0) { direction = 1; if (index == this.banners.length - 1 && this.index == 0) { direction = -1; } } else { if (index == 0 && this.index == this.banners.length - 1) { direction = 1; } } //this.log('direction=' + direction); if (this.index != null) { if ('slide' == this.effect) { banner.containerObj.style.left = direction * (this.width + this.htmlWidth) + 'px'; } else { this.banners[index].containerObj.style.display = 'none'; } } banner.containerObj.style.marginLeft = 0; //$('.banner_preload', this.container).remove(); $(this.itemContainer).append(banner.containerObj); this._animated = false; banner._animated = false; var obj = this; if (this.index != null) { if ('slide' == this.effect) { //this.log('animation ' + (-1 * direction * (this.width + this.htmlWidth)) + ' ' + this.effectDuration + ' ms'); $('.banner_item:first').animate( {marginLeft:-1 * direction * (this.width + this.htmlWidth)}, {duration: this.effectDuration} ); $('.banner_item:last').animate( {marginLeft:-1 * direction * (this.width + this.htmlWidth)}, { duration: this.effectDuration, complete: function () {obj.animationComplete(index, direction);} } ); } else { $(this.banners[this.index].containerObj).fadeOut(this.effectDuration); $(banner.containerObj).fadeIn( this.effectDuration, function () {obj.animationComplete(index, direction);} ); } } else { //this.log('no animation'); obj.animationComplete(index, direction); } }, animationComplete: function (index, direction) { var banner = this.banners[index]; if ($('.banner_item', this.container).size() > 1) { if (direction) { $('.banner_item:last', this.container).css({left: 0, marginLeft: 0}); $('.banner_item:first', this.container).remove(); } else { $('.banner_item:first', this.container).css({left: 0, marginLeft: 0}); $('.banner_item:last', this.container).remove(); } } this._animated = true; banner.showTime = false; this.setVisible(false, this.index); // mark previous bannas as invisible //this.log('show ' + this.index + '->' + index); 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 + this.htmlWidth); if (this.enableButtons) { paginatorWidth -= this.buttonsContainer.offsetWidth; } // $(this.paginatorContainer).css({width: paginatorWidth + 'px'}); this.paginatorOptions.containers = 'banner-toolbar-' + this.idItem; this.paginatorOptions.totalRecords = this.banners.length; this.paginatorOptions.totalRecords = this.banners.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.banners[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.banners.length == this.index + 1) ? 0 : this.index + 1; } else if ('left' == this.direction) { index = (0 == this.index) ? this.banners.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 banner = this.banners[index]; if (typeof banner.containerObj == 'undefined') { //this.log('preload ' + index); banner.containerObj = document.createElement('div'); banner.containerObj.className = 'banner_item'; banner.containerObj.style.width = (this.width + this.htmlWidth) + 'px'; banner.containerObj.style.height = this.height + 'px'; //if ('image' == banner.type) { /* image loader */ banner.containerObj.appendChild($('
').get(0)); /* html block start */ //obj.log('preloaded ' + index); var htmlContainer = document.createElement('div'); //htmlContainer.style.width = (this.htmlWidth - 20)/*(this.width - 20)*/ + 'px'; //htmlContainer.style.padding = '10px'; htmlContainer.className = 'banner_html'; if (banner.backgroundImage) { banner.containerObj.style.backgroundImage = "url('" + banner.backgroundImage + "')"; banner.containerObj.style.backgroundRepeat = 'no-repeat'; banner.containerObj.style.backgroundPosition = 'center center'; } htmlContainer.appendChild($('').get(0)); htmlContainer.appendChild($('
' + banner.html + '
').get(0)); banner.containerObj.appendChild(htmlContainer); /* html block finish */ var imageObj = new Image(); imageObj.setAttribute('useMap', '#banner_map_' + banner.id); imageObj.setAttribute('alt', banner.title); imageObj.onabort = function () {obj.onabort(this)}; imageObj.onerror = function () {obj.onerror(this)}; imageObj.style.display = 'none'; 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'; var container = qs.getParentTag(this, 'DIV'); $('.image_loading', $(container)).hide(); this.style.display = 'inline'; //obj.preloaded(index); } banner.containerObj.appendChild(imageObj); imageObj.src = banner.image; //if (banner.hotSpotMap != 'empty') { // var map = document.createElement('MAP'); // map.name = 'banner_map_' + banner.id; // map.id = 'banner_map_' + banner.id; // Fix IE6/IE7 area // for (var key in banner.hotSpotMap) { // var area = document.createElement( "AREA" ); // area.shape = banner.hotSpotMap[key].shape; // area.coords = banner.hotSpotMap[key].coords; // area.href = banner.hotSpotMap[key].href; // area.target = banner.hotSpotMap[key].target; // area.alt = banner.hotSpotMap[key].alt; // map.appendChild(area); // } // banner.containerObj.appendChild(map); //} obj.preloaded(index); // <-- !!!!!!!!!!!!!!!!!!!!! //} else if ('html' == banner.type) { // obj.log('preloaded ' + index); // var htmlContainer = document.createElement('div'); // htmlContainer.style.width = (this.htmlWidth - 20)/*(this.width - 20)*/ + 'px'; // htmlContainer.style.padding = '10px'; // htmlContainer.className = 'banner_html'; // if (banner.backgroundImage) { // banner.containerObj.style.backgroundImage = "url('" + banner.backgroundImage + "')"; // banner.containerObj.style.backgroundRepeat = 'no-repeat'; // banner.containerObj.style.backgroundPosition = 'center center'; // } // htmlContainer.appendChild($('').get(0)); // htmlContainer.appendChild($('
' + banner.html + '
').get(0)); // banner.containerObj.appendChild(htmlContainer); // obj.preloaded(index); //} } else { obj.preloaded(index); } }, preloaded: function (index) { //this.log('preloaded ' + index); var now = new Date(); var banner = this.banners[index]; if (false !== banner.showTime && Math.floor(now.getTime()/1000) >= Math.floor(banner.showTime/1000)) { if (this.autostart) { this.stop(); } this.show(index); if (this.autostart) { this.play(); } } else { this.log(banner.showTime + '\n' + now.getTime()); } }, log: function (text) { if (!this.debug || typeof console == 'undefined') { return false; } var message = 'index=' + this.index + '. [' + text + '] '; console.info(message); } }