Page Menu
Home
Code
Search
Configure Global Search
Log In
Files
F882492
ThumbnailPicker.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
16 KB
Subscribers
None
ThumbnailPicker.js
View Options
if
(
!
dojo
.
_hasResource
[
"dojox.image.ThumbnailPicker"
]){
//_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo
.
_hasResource
[
"dojox.image.ThumbnailPicker"
]
=
true
;
dojo
.
provide
(
"dojox.image.ThumbnailPicker"
);
dojo
.
experimental
(
"dojox.image.ThumbnailPicker"
);
//
// dojox.image.ThumbnailPicker courtesy Shane O Sullivan, licensed under a Dojo CLA
// @author Copyright 2007 Shane O Sullivan (shaneosullivan1@gmail.com)
//
// For a sample usage, see http://www.skynet.ie/~sos/photos.php
//
// document topics.
dojo
.
require
(
"dojo.fx"
);
dojo
.
require
(
"dijit._Widget"
);
dojo
.
require
(
"dijit._Templated"
);
dojo
.
declare
(
"dojox.image.ThumbnailPicker"
,
[
dijit
.
_Widget
,
dijit
.
_Templated
],
{
// summary: A scrolling Thumbnail Picker widget
//
// imageStore: Object
// A data store that implements the dojo.data Read API.
imageStore
:
null
,
// request: Object
// A dojo.data Read API Request object.
request
:
null
,
// size: Number
// Width or height in pixels, depending if horizontal or vertical.
size
:
500
,
// thumbHeight: Number
// Default height of a thumbnail image
thumbHeight
:
75
,
// thumbWidth: Number
// Default width of an image
thumbWidth
:
100
,
// useLoadNotifier: Boolean
// Setting useLoadNotifier to true makes a colored DIV appear under each
// thumbnail image, which is used to display the loading status of each
// image in the data store.
useLoadNotifier
:
false
,
// useHyperlink: boolean
// Setting useHyperlink to true causes a click on a thumbnail to open a link.
useHyperlink
:
false
,
// hyperlinkTarget: String
// If hyperlinkTarget is set to "new", clicking on a thumb will open a new window
// If it is set to anything else, clicking a thumbnail will open the url in the
// current window.
hyperlinkTarget
:
"new"
,
// isClickable: Boolean
// When set to true, the cursor over a thumbnail changes.
isClickable
:
true
,
// isScrollable: Boolean
// When true, uses smoothScroll to move between pages
isScrollable
:
true
,
// isHorizontal: Boolean
// If true, the thumbnails are displayed horizontally. Otherwise they are displayed
// vertically
isHorizontal
:
true
,
//autoLoad: Boolean
autoLoad
:
true
,
// linkAttr: String
// The attribute name for accessing the url from the data store
linkAttr
:
"link"
,
// imageThumbAttr: String
// The attribute name for accessing the thumbnail image url from the data store
imageThumbAttr
:
"imageUrlThumb"
,
// imageLargeAttr: String
// The attribute name for accessing the large image url from the data store
imageLargeAttr
:
"imageUrl"
,
// pageSize: Number
// The number of images to request each time.
pageSize
:
20
,
// titleAttr: String
// The attribute name for accessing the title from the data store
titleAttr
:
"title"
,
templateString
:
"<div dojoAttachPoint=\"outerNode\" class=\"thumbOuter\">\n\t<div dojoAttachPoint=\"navPrev\" class=\"thumbNav thumbClickable\">\n\t <img src=\"\" dojoAttachPoint=\"navPrevImg\"/> \n\t</div>\n\t<div dojoAttachPoint=\"thumbScroller\" class=\"thumbScroller\">\n\t <div dojoAttachPoint=\"thumbsNode\" class=\"thumbWrapper\"></div>\n\t</div>\n\t<div dojoAttachPoint=\"navNext\" class=\"thumbNav thumbClickable\">\n\t <img src=\"\" dojoAttachPoint=\"navNextImg\"/> \n\t</div>\n</div>\n"
,
tempImgPath
:
dojo
.
moduleUrl
(
"dojox.image"
,
"resources/images/1pixel.gif"
),
// thumbs: Array
// Stores the image nodes for the thumbnails.
_thumbs
:
[],
// _thumbIndex: Number
// The index of the first thumbnail shown
_thumbIndex
:
0
,
// _maxPhotos: Number
// The total number of photos in the image store
_maxPhotos
:
0
,
// _loadedImages: Object
// Stores the indices of images that have been marked as loaded using the
// markImageLoaded function.
_loadedImages
:
{},
postCreate
:
function
(){
// summary: Initializes styles and listeners
this
.
widgetid
=
this
.
id
;
this
.
inherited
(
"postCreate"
,
arguments
);
this
.
pageSize
=
Number
(
this
.
pageSize
);
this
.
_scrollerSize
=
this
.
size
-
(
51
*
2
);
var
sizeProp
=
this
.
_sizeProperty
=
this
.
isHorizontal
?
"width"
:
"height"
;
// FIXME: do this via css? calculate the correct width for the widget
dojo
.
style
(
this
.
outerNode
,
"textAlign"
,
"center"
);
dojo
.
style
(
this
.
outerNode
,
sizeProp
,
this
.
size
+
"px"
);
dojo
.
style
(
this
.
thumbScroller
,
sizeProp
,
this
.
_scrollerSize
+
"px"
);
//If useHyperlink is true, then listen for a click on a thumbnail, and
//open the link
if
(
this
.
useHyperlink
){
dojo
.
subscribe
(
this
.
getClickTopicName
(),
this
,
function
(
packet
){
var
index
=
packet
.
index
;
var
url
=
this
.
imageStore
.
getValue
(
packet
.
data
,
this
.
linkAttr
);
//If the data item doesn't contain a URL, do nothing
if
(
!
url
){
return
;}
if
(
this
.
hyperlinkTarget
==
"new"
){
window
.
open
(
url
);
}
else
{
window
.
location
=
url
;
}
});
}
if
(
this
.
isScrollable
)
{
dojo
.
require
(
"dojox.fx.scroll"
);
dojo
.
require
(
"dojox.fx.easing"
);
}
if
(
this
.
isClickable
){
dojo
.
addClass
(
this
.
thumbsNode
,
"thumbClickable"
);
}
this
.
_totalSize
=
0
;
this
.
init
();
},
init
:
function
(){
// summary: Creates DOM nodes for thumbnail images and initializes their listeners
if
(
this
.
isInitialized
)
{
return
false
;}
var
classExt
=
this
.
isHorizontal
?
"Horiz"
:
"Vert"
;
// FIXME: can we setup a listener around the whole element and determine based on e.target?
dojo
.
addClass
(
this
.
navPrev
,
"prev"
+
classExt
);
dojo
.
addClass
(
this
.
navNext
,
"next"
+
classExt
);
dojo
.
addClass
(
this
.
thumbsNode
,
"thumb"
+
classExt
);
dojo
.
addClass
(
this
.
outerNode
,
"thumb"
+
classExt
);
this
.
navNextImg
.
setAttribute
(
"src"
,
this
.
tempImgPath
);
this
.
navPrevImg
.
setAttribute
(
"src"
,
this
.
tempImgPath
);
dojo
.
connect
(
this
.
navPrev
,
"onclick"
,
this
,
"_prev"
);
dojo
.
connect
(
this
.
navNext
,
"onclick"
,
this
,
"_next"
);
this
.
isInitialized
=
true
;
if
(
this
.
isHorizontal
){
this
.
_offsetAttr
=
"offsetLeft"
;
this
.
_sizeAttr
=
"offsetWidth"
;
this
.
_scrollAttr
=
"scrollLeft"
;
}
else
{
this
.
_offsetAttr
=
"offsetTop"
;
this
.
_sizeAttr
=
"offsetHeight"
;
this
.
_scrollAttr
=
"scrollTop"
;
}
this
.
_updateNavControls
();
if
(
this
.
imageStore
&&
this
.
request
){
this
.
_loadNextPage
();}
return
true
;
},
getClickTopicName
:
function
(){
// summary: Returns the name of the dojo topic that can be
// subscribed to in order to receive notifications on
// which thumbnail was selected.
return
(
this
.
widgetId
?
this
.
widgetId
:
this
.
id
)
+
"/select"
;
// String
},
getShowTopicName
:
function
(){
// summary: Returns the name of the dojo topic that can be
// subscribed to in order to receive notifications on
// which thumbnail is now visible
return
(
this
.
widgetId
?
this
.
widgetId
:
this
.
id
)
+
"/show"
;
// String
},
setDataStore
:
function
(
dataStore
,
request
,
/*optional*/
paramNames
){
// summary: Sets the data store and request objects to read data from.
// dataStore:
// An implementation of the dojo.data.api.Read API. This accesses the image
// data.
// request:
// An implementation of the dojo.data.api.Request API. This specifies the
// query and paging information to be used by the data store
// paramNames:
// An object defining the names of the item attributes to fetch from the
// data store. The four attributes allowed are 'linkAttr', 'imageLargeAttr',
// 'imageThumbAttr' and 'titleAttr'
this
.
reset
();
this
.
request
=
{
query
:
{},
start
:
request
.
start
?
request
.
start
:
0
,
count
:
request
.
count
?
request
.
count
:
10
,
onBegin
:
dojo
.
hitch
(
this
,
function
(
total
){
this
.
_maxPhotos
=
total
;
})
};
if
(
request
.
query
){
dojo
.
mixin
(
this
.
request
.
query
,
request
.
query
);}
if
(
paramNames
&&
paramNames
.
imageThumbAttr
){
var
attrNames
=
[
"imageThumbAttr"
,
"imageLargeAttr"
,
"linkAttr"
,
"titleAttr"
];
for
(
var
i
=
0
;
i
<
attrNames
.
length
;
i
++
){
if
(
paramNames
[
attrNames
[
i
]]){
this
[
attrNames
[
i
]]
=
paramNames
[
attrNames
[
i
]];}
}
}
this
.
request
.
start
=
0
;
this
.
request
.
count
=
this
.
pageSize
;
this
.
imageStore
=
dataStore
;
if
(
!
this
.
init
()){
this
.
_loadNextPage
();}
},
reset
:
function
(){
// summary: Resets the widget back to its original state.
this
.
_loadedImages
=
{};
var
img
;
for
(
var
pos
=
0
;
pos
<
this
.
_thumbs
.
length
;
pos
++
){
img
=
this
.
_thumbs
[
pos
];
if
(
img
){
// dojo.event.browser.clean(img);
if
(
img
.
parentNode
){
img
.
parentNode
.
removeChild
(
img
);
}
}
}
this
.
_thumbs
=
[];
this
.
isInitialized
=
false
;
this
.
_noImages
=
true
;
},
isVisible
:
function
(
idx
)
{
// summary: Returns true if the image at the specified index is currently visible. False otherwise.
var
img
=
this
.
_thumbs
[
idx
];;
if
(
!
img
){
return
false
;}
var
pos
=
this
.
isHorizontal
?
"offsetLeft"
:
"offsetTop"
;
var
size
=
this
.
isHorizontal
?
"offsetWidth"
:
"offsetHeight"
;
var
scrollAttr
=
this
.
isHorizontal
?
"scrollLeft"
:
"scrollTop"
;
var
offset
=
img
[
pos
]
-
this
.
thumbsNode
[
pos
];
return
(
offset
>=
this
.
thumbScroller
[
scrollAttr
]
&&
offset
+
img
[
size
]
<=
this
.
thumbScroller
[
scrollAttr
]
+
this
.
_scrollerSize
);
},
_next
:
function
()
{
// summary: Displays the next page of images
var
pos
=
this
.
isHorizontal
?
"offsetLeft"
:
"offsetTop"
;
var
size
=
this
.
isHorizontal
?
"offsetWidth"
:
"offsetHeight"
;
var
baseOffset
=
this
.
thumbsNode
[
pos
];
var
firstThumb
=
this
.
_thumbs
[
this
.
_thumbIndex
];
var
origOffset
=
firstThumb
[
pos
]
-
baseOffset
;
var
idx
=
-
1
,
img
;
for
(
var
i
=
this
.
_thumbIndex
+
1
;
i
<
this
.
_thumbs
.
length
;
i
++
){
img
=
this
.
_thumbs
[
i
];
if
(
img
[
pos
]
-
baseOffset
+
img
[
size
]
-
origOffset
>
this
.
_scrollerSize
){
this
.
_showThumbs
(
i
);
return
;
}
}
},
_prev
:
function
(){
// summary: Displays the next page of images
if
(
this
.
thumbScroller
[
this
.
isHorizontal
?
"scrollLeft"
:
"scrollTop"
]
==
0
){
return
;}
var
pos
=
this
.
isHorizontal
?
"offsetLeft"
:
"offsetTop"
;
var
size
=
this
.
isHorizontal
?
"offsetWidth"
:
"offsetHeight"
;
var
firstThumb
=
this
.
_thumbs
[
this
.
_thumbIndex
];
var
origOffset
=
firstThumb
[
pos
]
-
this
.
thumbsNode
[
pos
];
var
idx
=
-
1
,
img
;
for
(
var
i
=
this
.
_thumbIndex
-
1
;
i
>
-
1
;
i
--
)
{
img
=
this
.
_thumbs
[
i
];
if
(
origOffset
-
img
[
pos
]
>
this
.
_scrollerSize
){
this
.
_showThumbs
(
i
+
1
);
return
;
}
}
this
.
_showThumbs
(
0
);
},
_checkLoad
:
function
(
img
,
idx
){
dojo
.
publish
(
this
.
getShowTopicName
(),
[{
index
:
idx
}]);
this
.
_updateNavControls
();
this
.
_loadingImages
=
{};
this
.
_thumbIndex
=
idx
;
//If we have not already requested the data from the store, do so.
if
(
this
.
thumbsNode
.
offsetWidth
-
img
.
offsetLeft
<
(
this
.
_scrollerSize
*
2
)){
this
.
_loadNextPage
();
}
},
_showThumbs
:
function
(
idx
){
// summary: Displays thumbnail images, starting at position 'idx'
// idx: Number
// The index of the first thumbnail
var
_this
=
this
;
var
idx
=
arguments
.
length
==
0
?
this
.
_thumbIndex
:
arguments
[
0
];
idx
=
Math
.
min
(
Math
.
max
(
idx
,
0
),
this
.
_maxPhotos
);
if
(
idx
>=
this
.
_maxPhotos
){
return
;
}
var
img
=
this
.
_thumbs
[
idx
];
if
(
!
img
){
return
;
}
var
left
=
img
.
offsetLeft
-
this
.
thumbsNode
.
offsetLeft
;
var
top
=
img
.
offsetTop
-
this
.
thumbsNode
.
offsetTop
;
var
offset
=
this
.
isHorizontal
?
left
:
top
;
if
(
(
offset
>=
this
.
thumbScroller
[
this
.
_scrollAttr
])
&&
(
offset
+
img
[
this
.
_sizeAttr
]
<=
this
.
thumbScroller
[
this
.
_scrollAttr
]
+
this
.
_scrollerSize
)
){
// FIXME: WTF is this checking for?
return
;
}
if
(
this
.
isScrollable
){
var
target
=
this
.
isHorizontal
?
{
x
:
left
,
y
:
0
}
:
{
x
:
0
,
y
:
top
};
dojox
.
fx
.
smoothScroll
({
target
:
target
,
win
:
this
.
thumbScroller
,
duration
:
300
,
easing
:
dojox
.
fx
.
easing
.
easeOut
,
onEnd
:
dojo
.
hitch
(
this
,
"_checkLoad"
,
img
,
idx
)
}).
play
(
10
);
}
else
{
if
(
this
.
isHorizontal
){
this
.
thumbScroller
.
scrollLeft
=
left
;
}
else
{
this
.
thumbScroller
.
scrollTop
=
top
;
}
this
.
_checkLoad
(
img
,
idx
);
}
},
markImageLoaded
:
function
(
index
){
// summary: Changes a visual cue to show the image is loaded
// description: If 'useLoadNotifier' is set to true, then a visual cue is
// given to state whether the image is loaded or not. Calling this function
// marks an image as loaded.
var
thumbNotifier
=
dojo
.
byId
(
"loadingDiv_"
+
this
.
widgetid
+
"_"
+
index
);
if
(
thumbNotifier
){
this
.
_setThumbClass
(
thumbNotifier
,
"thumbLoaded"
);}
this
.
_loadedImages
[
index
]
=
true
;
},
_setThumbClass
:
function
(
thumb
,
className
){
// summary: Adds a CSS class to a thumbnail, only if 'autoLoad' is true
// thumb: DomNode
// The thumbnail DOM node to set the class on
// className: String
// The CSS class to add to the DOM node.
if
(
!
this
.
autoLoad
){
return
;
}
dojo
.
addClass
(
thumb
,
className
);
},
_loadNextPage
:
function
(){
// summary: Loads the next page of thumbnail images
if
(
this
.
_loadInProgress
){
return
;}
this
.
_loadInProgress
=
true
;
var
start
=
this
.
request
.
start
+
(
this
.
_noImages
==
true
?
0
:
this
.
pageSize
);
var
pos
=
start
;
while
(
pos
<
this
.
_thumbs
.
length
&&
this
.
_thumbs
[
pos
]){
pos
++
;}
var
_this
=
this
;
//Define the function to call when the items have been
//returned from the data store.
var
complete
=
function
(
items
,
request
){
if
(
items
&&
items
.
length
)
{
var
itemCounter
=
0
;
var
loadNext
=
function
(){
if
(
itemCounter
>=
items
.
length
){
_this
.
_loadInProgress
=
false
;
return
;
}
var
counter
=
itemCounter
++
;
_this
.
_loadImage
(
items
[
counter
],
pos
+
counter
,
loadNext
);
}
loadNext
();
//Show or hide the navigation arrows on the thumbnails,
//depending on whether or not the widget is at the start,
//end, or middle of the list of images.
_this
.
_updateNavControls
();
}
else
{
_this
.
_loadInProgress
=
false
;
}
};
//Define the function to call if the store reports an error.
var
error
=
function
(){
_this
.
_loadInProgress
=
false
;
console
.
debug
(
"Error getting items"
);
};
this
.
request
.
onComplete
=
complete
;
this
.
request
.
onError
=
error
;
//Increment the start parameter. This is the dojo.data API's
//version of paging.
this
.
request
.
start
=
start
;
this
.
_noImages
=
false
;
//Execute the request for data.
this
.
imageStore
.
fetch
(
this
.
request
);
},
_loadImage
:
function
(
data
,
index
,
callback
){
var
url
=
this
.
imageStore
.
getValue
(
data
,
this
.
imageThumbAttr
);
var
img
=
document
.
createElement
(
"img"
);
var
imgContainer
=
document
.
createElement
(
"div"
);
imgContainer
.
setAttribute
(
"id"
,
"img_"
+
this
.
widgetid
+
"_"
+
index
);
imgContainer
.
appendChild
(
img
);
img
.
_index
=
index
;
img
.
_data
=
data
;
this
.
_thumbs
[
index
]
=
imgContainer
;
var
loadingDiv
;
if
(
this
.
useLoadNotifier
){
loadingDiv
=
document
.
createElement
(
"div"
);
loadingDiv
.
setAttribute
(
"id"
,
"loadingDiv_"
+
this
.
widgetid
+
"_"
+
index
);
//If this widget was previously told that the main image for this
//thumb has been loaded, make the loading indicator transparent.
this
.
_setThumbClass
(
loadingDiv
,
this
.
_loadedImages
[
index
]
?
"thumbLoaded"
:
"thumbNotifier"
);
imgContainer
.
appendChild
(
loadingDiv
);
}
var
size
=
dojo
.
marginBox
(
this
.
thumbsNode
);
var
defaultSize
;
var
sizeParam
;
if
(
this
.
isHorizontal
){
defaultSize
=
this
.
thumbWidth
;
sizeParam
=
'w'
;
}
else
{
defaultSize
=
this
.
thumbHeight
;
sizeParam
=
'h'
;
}
size
=
size
[
sizeParam
];
var
sl
=
this
.
thumbScroller
.
scrollLeft
,
st
=
this
.
thumbScroller
.
scrollTop
;
dojo
.
style
(
this
.
thumbsNode
,
this
.
_sizeProperty
,
(
size
+
defaultSize
+
20
)
+
"px"
);
//Remember the scroll values, as changing the size can alter them
this
.
thumbScroller
.
scrollLeft
=
sl
;
this
.
thumbScroller
.
scrollTop
=
st
;
this
.
thumbsNode
.
appendChild
(
imgContainer
);
dojo
.
connect
(
img
,
"onload"
,
this
,
function
(){
var
realSize
=
dojo
.
marginBox
(
img
)[
sizeParam
];
this
.
_totalSize
+=
(
Number
(
realSize
)
+
4
);
dojo
.
style
(
this
.
thumbsNode
,
this
.
_sizeProperty
,
this
.
_totalSize
+
"px"
);
if
(
this
.
useLoadNotifier
){
dojo
.
style
(
loadingDiv
,
"width"
,
(
img
.
width
-
4
)
+
"px"
);
}
callback
();
return
false
;
});
dojo
.
connect
(
img
,
"onclick"
,
this
,
function
(
evt
){
dojo
.
publish
(
this
.
getClickTopicName
(),
[{
index
:
evt
.
target
.
_index
,
data
:
evt
.
target
.
_data
,
url
:
img
.
getAttribute
(
"src"
),
largeUrl
:
this
.
imageStore
.
getValue
(
data
,
this
.
imageLargeAttr
),
title
:
this
.
imageStore
.
getValue
(
data
,
this
.
titleAttr
),
link
:
this
.
imageStore
.
getValue
(
data
,
this
.
linkAttr
)
}]);
return
false
;
});
dojo
.
addClass
(
img
,
"imageGalleryThumb"
);
img
.
setAttribute
(
"src"
,
url
);
var
title
=
this
.
imageStore
.
getValue
(
data
,
this
.
titleAttr
);
if
(
title
){
img
.
setAttribute
(
"title"
,
title
);
}
this
.
_updateNavControls
();
},
_updateNavControls
:
function
(){
// summary: Updates the navigation controls to hide/show them when at
// the first or last images.
var
cells
=
[];
var
change
=
function
(
node
,
add
){
var
fn
=
add
?
"addClass"
:
"removeClass"
;
dojo
[
fn
](
node
,
"enabled"
);
dojo
[
fn
](
node
,
"thumbClickable"
);
};
var
pos
=
this
.
isHorizontal
?
"scrollLeft"
:
"scrollTop"
;
var
size
=
this
.
isHorizontal
?
"offsetWidth"
:
"offsetHeight"
;
change
(
this
.
navPrev
,
(
this
.
thumbScroller
[
pos
]
>
0
));
var
last
=
this
.
_thumbs
[
this
.
_thumbs
.
length
-
1
];
var
addClass
=
(
this
.
thumbScroller
[
pos
]
+
this
.
_scrollerSize
<
this
.
thumbsNode
[
size
]);
change
(
this
.
navNext
,
addClass
);
}
});
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 2, 13:42 (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25104
Default Alt Text
ThumbnailPicker.js (16 KB)
Attached To
rZEDHG ZedLegacy
Event Timeline
Log In to Comment