diff options
Diffstat (limited to 'js/dojo/dojox/mobile/Carousel.js')
| -rw-r--r-- | js/dojo/dojox/mobile/Carousel.js | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/js/dojo/dojox/mobile/Carousel.js b/js/dojo/dojox/mobile/Carousel.js new file mode 100644 index 0000000..cc2a2d1 --- /dev/null +++ b/js/dojo/dojox/mobile/Carousel.js @@ -0,0 +1,323 @@ +//>>built +define("dojox/mobile/Carousel", [ + "dojo/_base/kernel", + "dojo/_base/array", + "dojo/_base/connect", + "dojo/_base/declare", + "dojo/_base/event", + "dojo/_base/lang", + "dojo/_base/sniff", + "dojo/dom-class", + "dojo/dom-construct", + "dojo/dom-style", + "dijit/_Contained", + "dijit/_Container", + "dijit/_WidgetBase", + "./PageIndicator", + "./SwapView", + "require" +], function(kernel, array, connect, declare, event, lang, has, domClass, domConstruct, domStyle, Contained, Container, WidgetBase, PageIndicator, SwapView, require){ + +/*===== + var Contained = dijit._Contained; + var Container = dijit._Container; + var WidgetBase = dijit._WidgetBase; + var PageIndicator = dojox.mobile.PageIndicator; + var SwapView = dojox.mobile.SwapView; +=====*/ + + // module: + // dojox/mobile/Carousel + // summary: + // A carousel widget that manages a list of images + + kernel.experimental("dojox.mobile.Carousel"); + + return declare("dojox.mobile.Carousel", [WidgetBase, Container, Contained], { + // summary: + // A carousel widget that manages a list of images + // description: + // The carousel widget manages a list of images that can be + // displayed horizontally, and allows the user to scroll through + // the list and select a single item. + + // numVisible: Number + // The number of visible items. + numVisible: 3, + + // title: String + // A title of the carousel to be displayed on the title bar. + title: "", + + // pageIndicator: Boolean + // If true, a page indicator, a series of small dots that indicate + // the current page, is displayed on the title bar. + pageIndicator: true, + + // navButton: Boolean + // If true, navigation buttons are displyaed on the title bar. + navButton: false, + + // height: String + // Explicitly specified height of the widget (ex. "300px"). If + // "inherit" is specified, the height is inherited from its offset + // parent. + height: "300px", + + // store: Object + // Reference to data provider object used by this widget. + store: null, + + // query: Object + // A query that can be passed to 'store' to initially filter the + // items. + query: null, + + // queryOptions: Object + // An optional parameter for the query. + queryOptions: null, + + buildRendering: function(){ + this.inherited(arguments); + this.domNode.className = "mblCarousel"; + var h; + if(this.height === "inherit"){ + if(this.domNode.offsetParent){ + h = this.domNode.offsetParent.offsetHeight + "px"; + } + }else if(this.height){ + h = this.height; + } + this.domNode.style.height = h; + this.headerNode = domConstruct.create("DIV", {className:"mblCarouselHeaderBar"}, this.domNode); + + if(this.navButton){ + this.btnContainerNode = domConstruct.create("DIV", { + className: "mblCarouselBtnContainer" + }, this.headerNode); + domStyle.set(this.btnContainerNode, "float", "right"); // workaround for webkit rendering problem + this.prevBtnNode = domConstruct.create("BUTTON", { + className: "mblCarouselBtn", + title: "Previous", + innerHTML: "<" + }, this.btnContainerNode); + this.nextBtnNode = domConstruct.create("BUTTON", { + className: "mblCarouselBtn", + title: "Next", + innerHTML: ">" + }, this.btnContainerNode); + this.connect(this.prevBtnNode, "onclick", "onPrevBtnClick"); + this.connect(this.nextBtnNode, "onclick", "onNextBtnClick"); + } + + if(this.pageIndicator){ + if(!this.title){ + this.title = " "; + } + this.piw = new PageIndicator(); + domStyle.set(this.piw, "float", "right"); // workaround for webkit rendering problem + this.headerNode.appendChild(this.piw.domNode); + } + + this.titleNode = domConstruct.create("DIV", { + className: "mblCarouselTitle" + }, this.headerNode); + + this.containerNode = domConstruct.create("DIV", {className:"mblCarouselPages"}, this.domNode); + connect.subscribe("/dojox/mobile/viewChanged", this, "handleViewChanged"); + }, + + startup: function(){ + if(this._started){ return; } + if(this.store){ + var store = this.store; + this.store = null; + this.setStore(store, this.query, this.queryOptions); + } + this.inherited(arguments); + }, + + setStore: function(store, query, queryOptions){ + // summary: + // Sets the store to use with this widget. + if(store === this.store){ return; } + this.store = store; + this.query = query; + this.queryOptions = queryOptions; + this.refresh(); + }, + + refresh: function(){ + if(!this.store){ return; } + this.store.fetch({ + query: this.query, + queryOptions: this.queryOptions, + onComplete: lang.hitch(this, "generate"), + onError: lang.hitch(this, "onError") + }); + }, + + generate: function(/*Array*/items, /*Object*/ dataObject){ + array.forEach(this.getChildren(), function(child){ + if(child instanceof SwapView){ + child.destroyRecursive(); + } + }); + this.items = items; + this.swapViews = []; + this.images = []; + var nPages = Math.ceil(items.length / this.numVisible); + var h = this.domNode.offsetHeight - this.headerNode.offsetHeight; + for(var i = 0; i < nPages; i++){ + var w = new SwapView({height:h+"px"}); + this.addChild(w); + this.swapViews.push(w); + w._carouselImages = []; + if(i === 0 && this.piw){ + this.piw.refId = w.id; + } + for(var j = 0; j < this.numVisible; j++){ + var idx = i * this.numVisible + j; + var item = idx < items.length ? items[idx] : + {src:require.toUrl("dojo/resources/blank.gif"), height:"1px"}; + var disp = w.domNode.style.display; + w.domNode.style.display = ""; // need to be visible during the size calculation + var box = this.createBox(item, h); + w.containerNode.appendChild(box); + box.appendChild(this.createHeaderText(item)); + var img = this.createContent(item, idx); + box.appendChild(img); + box.appendChild(this.createFooterText(item)); + this.resizeContent(item, box, img); + w.domNode.style.display = disp; + + if(item.height !== "1px"){ + this.images.push(img); + w._carouselImages.push(img); + } + } + } + if(this.swapViews[0]){ + this.loadImages(this.swapViews[0]); + } + if(this.swapViews[1]){ + this.loadImages(this.swapViews[1]); // pre-fetch the next view images + } + this.currentView = this.swapViews[0]; + if(this.piw){ + this.piw.reset(); + } + }, + + createBox: function(item, h){ + var width = item.width || (90/this.numVisible + "%"); + var height = item.height || h + "px"; + var m = has("ie") ? 5/this.numVisible-1 : 5/this.numVisible; + var margin = item.margin || (m + "%"); + var box = domConstruct.create("DIV", { + className: "mblCarouselBox" + }); + domStyle.set(box, { + margin: "0px " + margin, + width: width, + height: height + }); + return box; + }, + + createHeaderText: function(item){ + this.headerTextNode = domConstruct.create("DIV", { + className: "mblCarouselImgHeaderText", + innerHTML: item.headerText ? item.headerText : " " + }); + return this.headerTextNode; + }, + + createContent: function(item, idx){ + var props = { + alt: item.alt || "", + tabIndex: "0", // for keyboard navigation on a desktop browser + className: "mblCarouselImg" + }; + var img = domConstruct.create("IMG", props); + img._idx = idx; + if(item.height !== "1px"){ + this.connect(img, "onclick", "onClick"); + this.connect(img, "onkeydown", "onClick"); + connect.connect(img, "ondragstart", event.stop); + }else{ + img.style.visibility = "hidden"; + } + return img; + }, + + createFooterText: function(item){ + this.footerTextNode = domConstruct.create("DIV", { + className: "mblCarouselImgFooterText", + innerHTML: item.footerText ? item.footerText : " " + }); + return this.footerTextNode; + }, + + resizeContent: function(item, box, img){ + if(item.height !== "1px"){ + img.style.height = (box.offsetHeight - this.headerTextNode.offsetHeight - this.footerTextNode.offsetHeight) + "px"; + } + }, + + onError: function(errText){ + }, + + onPrevBtnClick: function(e){ + if(this.currentView){ + this.currentView.goTo(-1); + } + }, + + onNextBtnClick: function(e){ + if(this.currentView){ + this.currentView.goTo(1); + } + }, + + onClick: function(e){ + if(e && e.type === "keydown" && e.keyCode !== 13){ return; } + var img = e.currentTarget; + for(var i = 0; i < this.images.length; i++){ + if(this.images[i] === img){ + domClass.add(img, "mblCarouselImgSelected"); + }else{ + domClass.remove(this.images[i], "mblCarouselImgSelected"); + } + } + domStyle.set(img, "opacity", 0.4); + setTimeout(function(){ + domStyle.set(img, "opacity", 1); + }, 1000); + connect.publish("/dojox/mobile/carouselSelect", [this, img, this.items[img._idx], img._idx]); + }, + + loadImages: function(view){ + if(!view){ return; } + var imgs = view._carouselImages; + array.forEach(imgs, function(img){ + if(!img.src){ + var item = this.items[img._idx]; + img.src = item.src; + } + }, this); + }, + + handleViewChanged: function(view){ + if(view.getParent() !== this){ return; } + this.currentView = view; + // lazy-load images in the next view + this.loadImages(view.nextView(view.domNode)); + }, + + _setTitleAttr: function(/*String*/title){ + this.title = title; + this.titleNode.innerHTML = this._cv ? this._cv(title) : title; + } + }); +}); |
