--- /dev/null
+<html>\r
+<head>\r
+ <title>The source code</title>\r
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
+</head>\r
+<body onload="prettyPrint();">\r
+ <pre class="prettyprint lang-js">var ImageChooser = function(config){\r
+ this.config = config;\r
+}\r
+\r
+ImageChooser.prototype = {\r
+ // cache data by image name for easy lookup\r
+ lookup : {},\r
+\r
+ show : function(el, callback){\r
+ if(!this.win){\r
+ this.initTemplates();\r
+\r
+ this.store = new Ext.data.JsonStore({\r
+ url: this.config.url,\r
+ root: 'images',\r
+ fields: [\r
+ 'name', 'url',\r
+ {name:'size', type: 'float'},\r
+ {name:'lastmod', type:'date', dateFormat:'timestamp'}\r
+ ],\r
+ listeners: {\r
+ 'load': {fn:function(){ this.view.select(0); }, scope:this, single:true}\r
+ }\r
+ });\r
+ this.store.load();\r
+\r
+ var formatSize = function(data){\r
+ if(data.size < 1024) {\r
+ return data.size + " bytes";\r
+ } else {\r
+ return (Math.round(((data.size*10) / 1024))/10) + " KB";\r
+ }\r
+ };\r
+\r
+ var formatData = function(data){\r
+ data.shortName = data.name.ellipse(15);\r
+ data.sizeString = formatSize(data);\r
+ data.dateString = new Date(data.lastmod).format("m/d/Y g:i a");\r
+ this.lookup[data.name] = data;\r
+ return data;\r
+ };\r
+\r
+ this.view = new Ext.DataView({\r
+ tpl: this.thumbTemplate,\r
+ singleSelect: true,\r
+ overClass:'x-view-over',\r
+ itemSelector: 'div.thumb-wrap',\r
+ emptyText : '<div style="padding:10px;">No images match the specified filter</div>',\r
+ store: this.store,\r
+ listeners: {\r
+ 'selectionchange': {fn:this.showDetails, scope:this, buffer:100},\r
+ 'dblclick' : {fn:this.doCallback, scope:this},\r
+ 'loadexception' : {fn:this.onLoadException, scope:this},\r
+ 'beforeselect' : {fn:function(view){\r
+ return view.store.getRange().length > 0;\r
+ }}\r
+ },\r
+ prepareData: formatData.createDelegate(this)\r
+ });\r
+\r
+ var cfg = {\r
+ title: 'Choose an Image',\r
+ id: 'img-chooser-dlg',\r
+ layout: 'border',\r
+ minWidth: 500,\r
+ minHeight: 300,\r
+ modal: true,\r
+ closeAction: 'hide',\r
+ border: false,\r
+ items:[{\r
+ id: 'img-chooser-view',\r
+ region: 'center',\r
+ autoScroll: true,\r
+ items: this.view,\r
+ tbar:[{\r
+ text: 'Filter:'\r
+ },{\r
+ xtype: 'textfield',\r
+ id: 'filter',\r
+ selectOnFocus: true,\r
+ width: 100,\r
+ listeners: {\r
+ 'render': {fn:function(){\r
+ Ext.getCmp('filter').getEl().on('keyup', function(){\r
+ this.filter();\r
+ }, this, {buffer:500});\r
+ }, scope:this}\r
+ }\r
+ }, ' ', '-', {\r
+ text: 'Sort By:'\r
+ }, {\r
+ id: 'sortSelect',\r
+ xtype: 'combo',\r
+ typeAhead: true,\r
+ triggerAction: 'all',\r
+ width: 100,\r
+ editable: false,\r
+ mode: 'local',\r
+ displayField: 'desc',\r
+ valueField: 'name',\r
+ lazyInit: false,\r
+ value: 'name',\r
+ store: new Ext.data.ArrayStore({\r
+ fields: ['name', 'desc'],\r
+ data : [['name', 'Name'],['size', 'File Size'],['lastmod', 'Last Modified']]\r
+ }),\r
+ listeners: {\r
+ 'select': {fn:this.sortImages, scope:this}\r
+ }\r
+ }]\r
+ },{\r
+ id: 'img-detail-panel',\r
+ region: 'east',\r
+ split: true,\r
+ width: 150,\r
+ minWidth: 150,\r
+ maxWidth: 250\r
+ }],\r
+ buttons: [{\r
+ id: 'ok-btn',\r
+ text: 'OK',\r
+ handler: this.doCallback,\r
+ scope: this\r
+ },{\r
+ text: 'Cancel',\r
+ handler: function(){ this.win.hide(); },\r
+ scope: this\r
+ }],\r
+ keys: {\r
+ key: 27, // Esc key\r
+ handler: function(){ this.win.hide(); },\r
+ scope: this\r
+ }\r
+ };\r
+ Ext.apply(cfg, this.config);\r
+ this.win = new Ext.Window(cfg);\r
+ }\r
+\r
+ this.reset();\r
+ this.win.show(el);\r
+ this.callback = callback;\r
+ this.animateTarget = el;\r
+ },\r
+\r
+ initTemplates : function(){\r
+ this.thumbTemplate = new Ext.XTemplate(\r
+ '<tpl for=".">',\r
+ '<div class="thumb-wrap" id="{name}">',\r
+ '<div class="thumb"><img src="{url}" title="{name}"></div>',\r
+ '<span>{shortName}</span></div>',\r
+ '</tpl>'\r
+ );\r
+ this.thumbTemplate.compile();\r
+\r
+ this.detailsTemplate = new Ext.XTemplate(\r
+ '<div class="details">',\r
+ '<tpl for=".">',\r
+ '<img src="{url}"><div class="details-info">',\r
+ '<b>Image Name:</b>',\r
+ '<span>{name}</span>',\r
+ '<b>Size:</b>',\r
+ '<span>{sizeString}</span>',\r
+ '<b>Last Modified:</b>',\r
+ '<span>{dateString}</span></div>',\r
+ '</tpl>',\r
+ '</div>'\r
+ );\r
+ this.detailsTemplate.compile();\r
+ },\r
+\r
+ showDetails : function(){\r
+ var selNode = this.view.getSelectedNodes();\r
+ var detailEl = Ext.getCmp('img-detail-panel').body;\r
+ if(selNode && selNode.length > 0){\r
+ selNode = selNode[0];\r
+ Ext.getCmp('ok-btn').enable();\r
+ var data = this.lookup[selNode.id];\r
+ detailEl.hide();\r
+ this.detailsTemplate.overwrite(detailEl, data);\r
+ detailEl.slideIn('l', {stopFx:true,duration:.2});\r
+ }else{\r
+ Ext.getCmp('ok-btn').disable();\r
+ detailEl.update('');\r
+ }\r
+ },\r
+\r
+ filter : function(){\r
+ var filter = Ext.getCmp('filter');\r
+ this.view.store.filter('name', filter.getValue());\r
+ this.view.select(0);\r
+ },\r
+\r
+ sortImages : function(){\r
+ var v = Ext.getCmp('sortSelect').getValue();\r
+ this.view.store.sort(v, v == 'name' ? 'asc' : 'desc');\r
+ this.view.select(0);\r
+ },\r
+\r
+ reset : function(){\r
+ if(this.win.rendered){\r
+ Ext.getCmp('filter').reset();\r
+ this.view.getEl().dom.scrollTop = 0;\r
+ }\r
+ this.view.store.clearFilter();\r
+ this.view.select(0);\r
+ },\r
+\r
+ doCallback : function(){\r
+ var selNode = this.view.getSelectedNodes()[0];\r
+ var callback = this.callback;\r
+ var lookup = this.lookup;\r
+ this.win.hide(this.animateTarget, function(){\r
+ if(selNode && callback){\r
+ var data = lookup[selNode.id];\r
+ callback(data);\r
+ }\r
+ });\r
+ },\r
+\r
+ onLoadException : function(v,o){\r
+ this.view.getEl().update('<div style="padding:10px;">Error loading images.</div>');\r
+ }\r
+};\r
+\r
+String.prototype.ellipse = function(maxLength){\r
+ if(this.length > maxLength){\r
+ return this.substr(0, maxLength-3) + '...';\r
+ }\r
+ return this;\r
+};\r
+</pre> \r
+</body>\r
+</html>
\ No newline at end of file