flickr_viewer.html 7.02 KB
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html>
<head>
	<title>Sort Flickr images by tags</title>
	<style type="text/css">
		@import "../../resources/dojo.css";
		@import "../../resources/dnd.css";
		body {
			padding: 1em;
		}

		/* application-specific settings */
		#status					{font-weight: bold;}
		.container				{padding: 5px; cursor: default; background: #f8f8ff;}
		.wrap1					{float: left; width: 275px; height: 600px; overflow: auto; margin-right: 1em;}
		.wrap1 div				{min-height: 100px;}
		.wrap2					{width: 350px; height: 170px; overflow: auto;}
		.wrap2 div				{min-height: 150px;}
		.container .name		{font-weight: bold; padding-right: 4px;}
		.container .image		{padding: 5px;}
		body.dojoDndCopy, body.dojoDndMove	{color: #888;}
		.dojoDndCopy .container, .dojoDndMove .container	{background: #ddf;}
		
		/* container-specific settings */
		.dojoDndContainer		{border: 1px solid white; color: black;}
		.dojoDndContainerOver	{border: 1px solid black; color: black;}
		.container.dojoDndTargetDisabled	{background: #ccc; color: #888;}
		
		/* item-specific settings */
		.dojoDndItemOver		{background: #feb;}
		.dojoDndItemSelected	{background: #ccf; color: #444;}
		.dojoDndItemAnchor		{background: #ccf; color: black;}
		.dojoDndItemOver.dojoDndItemSelected	{background: #ec8;}
		.dojoDndItemOver.dojoDndItemAnchor		{background: #ec8;}
		.dojoDndItemBefore		{border-top:    3px solid red;}
		.dojoDndItemAfter		{border-bottom: 3px solid red;}
		.dojoDndHorizontal .dojoDndItemBefore		{border-top:    none;}
		.dojoDndHorizontal .dojoDndItemAfter		{border-bottom: none;}
		.dojoDndHorizontal .dojoDndItemBefore img	{border-left:  3px solid red;}
		.dojoDndHorizontal .dojoDndItemAfter img	{border-right: 3px solid red;}
	</style>
	<script type="text/javascript" src="../../dojo.js" data-dojo-config="isDebug: true, parseOnLoad: true"></script>

	<script type="text/javascript">
		require([
			"dojo/dom", "dojo/parser", "dojo/request/script",
			"dojo/dnd/common", "dojo/dnd/Avatar", "dojo/dnd/Source", "dojo/domReady!"
		], function(dom, parser, script, dnd, Avatar, Source){
		
			// The main image container creator
			main_creator = function(item, hint){
				var type = [];
				if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
				if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
				var node;
				if(hint == "avatar"){
					node = document.createElement("span");
					node.innerHTML = "<img src='" + item.media.m.replace(/_m\./, "_s.") + "'/>";
				}else{
					var t = ["<table border='0' cellpadding='0' cellspacing='0' width='250'>"];
					t.push("<tr><td colspan='2' class='image' align='center' width='250'><img src='" + 
						item.media.m + "'/></td></tr>");
					t.push("<tr><td class='name' valign='top'>Title:</td><td class='value'><a href='" + 
						item.link + "' target='_blank'>" + 
						(item.title ? item.title : "<em>untitled</em>") + "</a></td></tr>");
					t.push("<tr><td class='name' valign='top'>Author:</td><td class='value'>" + 
						item.author + "</td></tr>");
					t.push("<tr><td class='name' valign='top'>Tags:</td><td class='value'>" + 
						item.tags + "</td></tr>");
					t.push("</table>");
					node = document.createElement("div");
					node.innerHTML = t.join("");
				}
				node.id = dnd.getUniqueId();
				return {node: node, data: item, type: type};
			};
			
			// The band image container creator
			band_creator = function(item, hint){
				var type = [];
				if(item.tags.search(/cat/i) >= 0){ type.push("cat"); }
				if(item.tags.search(/dog/i) >= 0){ type.push("dog"); }
				var src = item.media.m.replace(/_m\./, "_s.");
				var node = document.createElement("span");
				node.innerHTML = "<img src='" + src + "'/>";
				node.id = dnd.getUniqueId();
				return {node: node, data: item, type: type};
			};
			
			// Flickr's JSONP function.
			jsonFlickrFeed = function(data){
				if(!data.items || !data.items.length){
					dom.byId("status").innerHTML = "Flickr didn't return any images";
					return;
				}
				dom.byId("status").innerHTML = data.items.length + " images were retrieved";
				// initialize sources
				c1.selectAll().deleteSelectedNodes();
				c2.selectAll().deleteSelectedNodes();
				c3.selectAll().deleteSelectedNodes();
				// populate the main source
				c1.insertNodes(false, data.items);
			};

			// replace the avatar string to make it more human readable
			Avatar.prototype._generateText = function(){
				return (this.manager.copy ? "copy" : "mov") + 
					"ing " + this.manager.nodes.length + " item" + 
					(this.manager.nodes.length != 1 ? "s" : "");
			};

			// Ask Flickr for images.   This calls jsonFlickrFeed rather than coming in the promise result, not sure why.
			script.get("http://api.flickr.com/services/feeds/photos_public.gne", {
				query: {tags: "cat,dog,cow", tagmode: "any", format: "json"},
				handleAs: "text/javascript",
				preventCache: true
			}).otherwise(
				function(){
					dom.byId("status").innerHTML = "Flickr failed to return images";
				}
			);
		});
	</script>
</head>
<body>
	<h1>Sort Flickr images by tags</h1>
	<p>This simple web application retrieves public images from Flickr that were tagged either as "cat", "dog", or "cow".
	You can copy/move images in different containers according to their tags.</p>
	<p>Following selection modes are supported by default:</p>
	<ul>
		<li>Simple click &mdash; selects a single element, all other elements will be unselected.</li>
		<li>Ctrl+click &mdash; toggles a selection state of an element (use Meta key on Mac).</li>
		<li>Shift+click &mdash; selects a range of element from the previous anchor to the current element.</li>
		<li>Ctrl+Shift+click &mdash; adds a range of element from the previous anchor to the current element (use Meta key on Mac).</li>
	</ul>
	<p>Following drop modes are supported by default:</p>
	<ul>
		<li>Simple drop &mdash; moves elements to the valid target removing them from the source. It can be used to reorganize elements within a single source/target.</li>
		<li>Ctrl+drop &mdash; copies elements to the valid target (use Meta key on Mac).</li>
	</ul>
	<p>Now scroll down and start dragging and dropping, rearrange images using DnD, copy and move them back!</p>
	<p>Status: <span id="status">retrieving a list of Flickr images...</span></p>
	<div class="wrap1">
		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c1" accept="cat, dog, cow" class="container">
			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return main_creator(item, hint);</script>
		</div>
	</div>
	<p>Tag: cat</p>
	<div class="wrap2">
		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c2" accept="cat" horizontal="true" class="container">
			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return band_creator(item, hint);</script>
		</div>
	</div>
	<p>Tag: dog</p>
	<div class="wrap2">
		<div data-dojo-type="dojo/dnd/Source" data-dojo-id="c3" accept="dog" horizontal="true" class="container">
			<script type="dojo/method" data-dojo-event="creator" data-dojo-args="item, hint">return band_creator(item, hint);</script>
		</div>
	</div>
</body>
</html>