1 | /*! |
---|
2 | * Ext JS Library 3.0.0 |
---|
3 | * Copyright(c) 2006-2009 Ext JS, LLC |
---|
4 | * licensing@extjs.com |
---|
5 | * http://www.extjs.com/license |
---|
6 | */ |
---|
7 | var ImageChooser = function(config){ |
---|
8 | this.config = config; |
---|
9 | } |
---|
10 | |
---|
11 | ImageChooser.prototype = { |
---|
12 | // cache data by image name for easy lookup |
---|
13 | lookup : {}, |
---|
14 | |
---|
15 | show : function(el, callback){ |
---|
16 | if(!this.win){ |
---|
17 | this.initTemplates(); |
---|
18 | |
---|
19 | this.store = new Ext.data.JsonStore({ |
---|
20 | url: this.config.url, |
---|
21 | root: 'images', |
---|
22 | fields: [ |
---|
23 | 'name', 'url', |
---|
24 | {name:'size', type: 'float'}, |
---|
25 | {name:'lastmod', type:'date', dateFormat:'timestamp'} |
---|
26 | ], |
---|
27 | listeners: { |
---|
28 | 'load': {fn:function(){ this.view.select(0); }, scope:this, single:true} |
---|
29 | } |
---|
30 | }); |
---|
31 | this.store.load(); |
---|
32 | |
---|
33 | var formatSize = function(data){ |
---|
34 | if(data.size < 1024) { |
---|
35 | return data.size + " bytes"; |
---|
36 | } else { |
---|
37 | return (Math.round(((data.size*10) / 1024))/10) + " KB"; |
---|
38 | } |
---|
39 | }; |
---|
40 | |
---|
41 | var formatData = function(data){ |
---|
42 | data.shortName = data.name.ellipse(15); |
---|
43 | data.sizeString = formatSize(data); |
---|
44 | data.dateString = new Date(data.lastmod).format("m/d/Y g:i a"); |
---|
45 | this.lookup[data.name] = data; |
---|
46 | return data; |
---|
47 | }; |
---|
48 | |
---|
49 | this.view = new Ext.DataView({ |
---|
50 | tpl: this.thumbTemplate, |
---|
51 | singleSelect: true, |
---|
52 | overClass:'x-view-over', |
---|
53 | itemSelector: 'div.thumb-wrap', |
---|
54 | emptyText : '<div style="padding:10px;">No images match the specified filter</div>', |
---|
55 | store: this.store, |
---|
56 | listeners: { |
---|
57 | 'selectionchange': {fn:this.showDetails, scope:this, buffer:100}, |
---|
58 | 'dblclick' : {fn:this.doCallback, scope:this}, |
---|
59 | 'loadexception' : {fn:this.onLoadException, scope:this}, |
---|
60 | 'beforeselect' : {fn:function(view){ |
---|
61 | return view.store.getRange().length > 0; |
---|
62 | }} |
---|
63 | }, |
---|
64 | prepareData: formatData.createDelegate(this) |
---|
65 | }); |
---|
66 | |
---|
67 | var cfg = { |
---|
68 | title: 'Choose an Image', |
---|
69 | id: 'img-chooser-dlg', |
---|
70 | layout: 'border', |
---|
71 | minWidth: 500, |
---|
72 | minHeight: 300, |
---|
73 | modal: true, |
---|
74 | closeAction: 'hide', |
---|
75 | border: false, |
---|
76 | items:[{ |
---|
77 | id: 'img-chooser-view', |
---|
78 | region: 'center', |
---|
79 | autoScroll: true, |
---|
80 | items: this.view, |
---|
81 | tbar:[{ |
---|
82 | text: 'Filter:' |
---|
83 | },{ |
---|
84 | xtype: 'textfield', |
---|
85 | id: 'filter', |
---|
86 | selectOnFocus: true, |
---|
87 | width: 100, |
---|
88 | listeners: { |
---|
89 | 'render': {fn:function(){ |
---|
90 | Ext.getCmp('filter').getEl().on('keyup', function(){ |
---|
91 | this.filter(); |
---|
92 | }, this, {buffer:500}); |
---|
93 | }, scope:this} |
---|
94 | } |
---|
95 | }, ' ', '-', { |
---|
96 | text: 'Sort By:' |
---|
97 | }, { |
---|
98 | id: 'sortSelect', |
---|
99 | xtype: 'combo', |
---|
100 | typeAhead: true, |
---|
101 | triggerAction: 'all', |
---|
102 | width: 100, |
---|
103 | editable: false, |
---|
104 | mode: 'local', |
---|
105 | displayField: 'desc', |
---|
106 | valueField: 'name', |
---|
107 | lazyInit: false, |
---|
108 | value: 'name', |
---|
109 | store: new Ext.data.ArrayStore({ |
---|
110 | fields: ['name', 'desc'], |
---|
111 | data : [['name', 'Name'],['size', 'File Size'],['lastmod', 'Last Modified']] |
---|
112 | }), |
---|
113 | listeners: { |
---|
114 | 'select': {fn:this.sortImages, scope:this} |
---|
115 | } |
---|
116 | }] |
---|
117 | },{ |
---|
118 | id: 'img-detail-panel', |
---|
119 | region: 'east', |
---|
120 | split: true, |
---|
121 | width: 150, |
---|
122 | minWidth: 150, |
---|
123 | maxWidth: 250 |
---|
124 | }], |
---|
125 | buttons: [{ |
---|
126 | id: 'ok-btn', |
---|
127 | text: 'OK', |
---|
128 | handler: this.doCallback, |
---|
129 | scope: this |
---|
130 | },{ |
---|
131 | text: 'Cancel', |
---|
132 | handler: function(){ this.win.hide(); }, |
---|
133 | scope: this |
---|
134 | }], |
---|
135 | keys: { |
---|
136 | key: 27, // Esc key |
---|
137 | handler: function(){ this.win.hide(); }, |
---|
138 | scope: this |
---|
139 | } |
---|
140 | }; |
---|
141 | Ext.apply(cfg, this.config); |
---|
142 | this.win = new Ext.Window(cfg); |
---|
143 | } |
---|
144 | |
---|
145 | this.reset(); |
---|
146 | this.win.show(el); |
---|
147 | this.callback = callback; |
---|
148 | this.animateTarget = el; |
---|
149 | }, |
---|
150 | |
---|
151 | initTemplates : function(){ |
---|
152 | this.thumbTemplate = new Ext.XTemplate( |
---|
153 | '<tpl for=".">', |
---|
154 | '<div class="thumb-wrap" id="{name}">', |
---|
155 | '<div class="thumb"><img src="{url}" title="{name}"></div>', |
---|
156 | '<span>{shortName}</span></div>', |
---|
157 | '</tpl>' |
---|
158 | ); |
---|
159 | this.thumbTemplate.compile(); |
---|
160 | |
---|
161 | this.detailsTemplate = new Ext.XTemplate( |
---|
162 | '<div class="details">', |
---|
163 | '<tpl for=".">', |
---|
164 | '<img src="{url}"><div class="details-info">', |
---|
165 | '<b>Image Name:</b>', |
---|
166 | '<span>{name}</span>', |
---|
167 | '<b>Size:</b>', |
---|
168 | '<span>{sizeString}</span>', |
---|
169 | '<b>Last Modified:</b>', |
---|
170 | '<span>{dateString}</span></div>', |
---|
171 | '</tpl>', |
---|
172 | '</div>' |
---|
173 | ); |
---|
174 | this.detailsTemplate.compile(); |
---|
175 | }, |
---|
176 | |
---|
177 | showDetails : function(){ |
---|
178 | var selNode = this.view.getSelectedNodes(); |
---|
179 | var detailEl = Ext.getCmp('img-detail-panel').body; |
---|
180 | if(selNode && selNode.length > 0){ |
---|
181 | selNode = selNode[0]; |
---|
182 | Ext.getCmp('ok-btn').enable(); |
---|
183 | var data = this.lookup[selNode.id]; |
---|
184 | detailEl.hide(); |
---|
185 | this.detailsTemplate.overwrite(detailEl, data); |
---|
186 | detailEl.slideIn('l', {stopFx:true,duration:.2}); |
---|
187 | }else{ |
---|
188 | Ext.getCmp('ok-btn').disable(); |
---|
189 | detailEl.update(''); |
---|
190 | } |
---|
191 | }, |
---|
192 | |
---|
193 | filter : function(){ |
---|
194 | var filter = Ext.getCmp('filter'); |
---|
195 | this.view.store.filter('name', filter.getValue()); |
---|
196 | this.view.select(0); |
---|
197 | }, |
---|
198 | |
---|
199 | sortImages : function(){ |
---|
200 | var v = Ext.getCmp('sortSelect').getValue(); |
---|
201 | this.view.store.sort(v, v == 'name' ? 'asc' : 'desc'); |
---|
202 | this.view.select(0); |
---|
203 | }, |
---|
204 | |
---|
205 | reset : function(){ |
---|
206 | if(this.win.rendered){ |
---|
207 | Ext.getCmp('filter').reset(); |
---|
208 | this.view.getEl().dom.scrollTop = 0; |
---|
209 | } |
---|
210 | this.view.store.clearFilter(); |
---|
211 | this.view.select(0); |
---|
212 | }, |
---|
213 | |
---|
214 | doCallback : function(){ |
---|
215 | var selNode = this.view.getSelectedNodes()[0]; |
---|
216 | var callback = this.callback; |
---|
217 | var lookup = this.lookup; |
---|
218 | this.win.hide(this.animateTarget, function(){ |
---|
219 | if(selNode && callback){ |
---|
220 | var data = lookup[selNode.id]; |
---|
221 | callback(data); |
---|
222 | } |
---|
223 | }); |
---|
224 | }, |
---|
225 | |
---|
226 | onLoadException : function(v,o){ |
---|
227 | this.view.getEl().update('<div style="padding:10px;">Error loading images.</div>'); |
---|
228 | } |
---|
229 | }; |
---|
230 | |
---|
231 | String.prototype.ellipse = function(maxLength){ |
---|
232 | if(this.length > maxLength){ |
---|
233 | return this.substr(0, maxLength-3) + '...'; |
---|
234 | } |
---|
235 | return this; |
---|
236 | }; |
---|