1 /** |
|
2 * Interface Elements for jQuery |
|
3 * Selectables |
|
4 * |
|
5 * http://interface.eyecon.ro |
|
6 * |
|
7 * Copyright (c) 2006 Stefan Petre |
|
8 * Dual licensed under the MIT (MIT-LICENSE.txt) |
|
9 * and GPL (GPL-LICENSE.txt) licenses. |
|
10 * |
|
11 * |
|
12 */ |
|
13 |
|
14 jQuery.selectHelper = null; |
|
15 jQuery.selectKeyHelper = false; |
|
16 jQuery.selectdrug = null; |
|
17 jQuery.selectCurrent = []; // For current selection |
|
18 jQuery.selectKeyDown = function(e) { |
|
19 var pressedKey = e.charCode || e.keyCode || -1; |
|
20 if (pressedKey == 17 || pressedKey == 16) { |
|
21 jQuery.selectKeyHelper = true; |
|
22 } |
|
23 }; |
|
24 jQuery.selectKeyUp = function(e) { |
|
25 jQuery.selectKeyHelper = false; |
|
26 }; |
|
27 jQuery.selectstart = function(e) { |
|
28 this.f.pointer = jQuery.iUtil.getPointer(e); |
|
29 this.f.pos = jQuery.extend( |
|
30 jQuery.iUtil.getPosition(this), |
|
31 jQuery.iUtil.getSize(this) |
|
32 ); |
|
33 |
|
34 this.f.scr = jQuery.iUtil.getScroll(this); |
|
35 this.f.pointer.x -= this.f.pos.x; |
|
36 this.f.pointer.y -= this.f.pos.y; |
|
37 jQuery(this).append(jQuery.selectHelper.get(0)); |
|
38 if (this.f.hc) |
|
39 jQuery.selectHelper.addClass(this.f.hc).css('display','block'); |
|
40 jQuery.selectHelper.css( |
|
41 { |
|
42 display: 'block', |
|
43 width: '0px', |
|
44 height: '0px' |
|
45 } |
|
46 ); |
|
47 if (this.f.o) { |
|
48 jQuery.selectHelper.css('opacity', this.f.o); |
|
49 } |
|
50 |
|
51 jQuery.selectdrug = this; |
|
52 jQuery.selectedone = false; |
|
53 jQuery.selectCurrent = []; // For current selection state |
|
54 this.f.el.each( |
|
55 function () |
|
56 { |
|
57 this.pos = { |
|
58 x: this.offsetLeft + (this.currentStyle && !jQuery.browser.opera ?parseInt(this.currentStyle.borderLeftWidth)||0:0) + (jQuery.selectdrug.scrollLeft||0), |
|
59 y: this.offsetTop + (this.currentStyle && !jQuery.browser.opera ?parseInt(this.currentStyle.borderTopWidth)||0:0) + (jQuery.selectdrug.scrollTop||0), |
|
60 wb: this.offsetWidth, |
|
61 hb: this.offsetHeight |
|
62 }; |
|
63 if (this.s == true) { |
|
64 if (jQuery.selectKeyHelper == false) { |
|
65 this.s = false; |
|
66 jQuery(this).removeClass(jQuery.selectdrug.f.sc); |
|
67 } else { |
|
68 jQuery.selectedone = true; |
|
69 |
|
70 // Save current state |
|
71 jQuery.selectCurrent[jQuery.selectCurrent.length] = jQuery.attr(this,'id'); |
|
72 } |
|
73 } |
|
74 } |
|
75 ); |
|
76 jQuery.selectcheck.apply(this, [e]); |
|
77 jQuery(document) |
|
78 .bind('mousemove', jQuery.selectcheck) |
|
79 .bind('mouseup', jQuery.selectstop); |
|
80 return false; |
|
81 }; |
|
82 jQuery.selectcheck = function(e) |
|
83 { |
|
84 if(!jQuery.selectdrug) |
|
85 return; |
|
86 jQuery.selectcheckApply.apply(jQuery.selectdrug, [e]); |
|
87 }; |
|
88 jQuery.selectcheckApply = function(e) |
|
89 { |
|
90 if(!jQuery.selectdrug) |
|
91 return; |
|
92 var pointer = jQuery.iUtil.getPointer(e); |
|
93 |
|
94 var scr = jQuery.iUtil.getScroll(jQuery.selectdrug); |
|
95 pointer.x += scr.l - this.f.scr.l - this.f.pos.x; |
|
96 pointer.y += scr.t - this.f.scr.t - this.f.pos.y; |
|
97 |
|
98 var sx = Math.min(pointer.x, this.f.pointer.x); |
|
99 var sw = Math.min(Math.abs(pointer.x - this.f.pointer.x), Math.abs(this.f.scr.w - sx)); |
|
100 var sy = Math.min(pointer.y, this.f.pointer.y); |
|
101 var sh = Math.min(Math.abs(pointer.y - this.f.pointer.y), Math.abs(this.f.scr.h - sy)); |
|
102 if (this.scrollTop > 0 && pointer.y - 20 < this.scrollTop) { |
|
103 var diff = Math.min(scr.t, 10); |
|
104 sy -= diff; |
|
105 sh += diff; |
|
106 this.scrollTop -= diff; |
|
107 } else if (this.scrollTop+ this.f.pos.h < this.f.scr.h && pointer.y + 20 > this.scrollTop + this.f.pos.h) { |
|
108 var diff = Math.min(this.f.scr.h - this.scrollTop, 10); |
|
109 this.scrollTop += diff; |
|
110 if (this.scrollTop != scr.t) |
|
111 sh += diff; |
|
112 } |
|
113 if (this.scrollLeft > 0 && pointer.x - 20 < this.scrollLeft) { |
|
114 var diff = Math.min(scr.l, 10); |
|
115 sx -= diff; |
|
116 sw += diff; |
|
117 this.scrollLeft -= diff; |
|
118 } else if (this.scrollLeft+ this.f.pos.w < this.f.scr.w && pointer.x + 20 > this.scrollLeft + this.f.pos.w) { |
|
119 var diff = Math.min(this.f.scr.w - this.scrollLeft, 10); |
|
120 this.scrollLeft += diff; |
|
121 if (this.scrollLeft != scr.l) |
|
122 sw += diff; |
|
123 } |
|
124 jQuery.selectHelper.css( |
|
125 { |
|
126 left: sx + 'px', |
|
127 top: sy + 'px', |
|
128 width: sw + 'px', |
|
129 height: sh + 'px' |
|
130 } |
|
131 ); |
|
132 jQuery.selectHelper.l = sx + this.f.scr.l; |
|
133 jQuery.selectHelper.t = sy + this.f.scr.t; |
|
134 jQuery.selectHelper.r = jQuery.selectHelper.l + sw; |
|
135 jQuery.selectHelper.b = jQuery.selectHelper.t + sh; |
|
136 jQuery.selectedone = false; |
|
137 this.f.el.each( |
|
138 function () { |
|
139 // Locate the current element in the current selection |
|
140 iIndex = jQuery.selectCurrent.indexOf(jQuery.attr(this, 'id')); |
|
141 // In case we are currently OVER an item |
|
142 if ( |
|
143 ! ( this.pos.x > jQuery.selectHelper.r |
|
144 || (this.pos.x + this.pos.wb) < jQuery.selectHelper.l |
|
145 || this.pos.y > jQuery.selectHelper.b |
|
146 || (this.pos.y + this.pos.hb) < jQuery.selectHelper.t |
|
147 ) |
|
148 ) |
|
149 { |
|
150 jQuery.selectedone = true; |
|
151 if (this.s != true) { |
|
152 this.s = true; |
|
153 jQuery(this).addClass(jQuery.selectdrug.f.sc); |
|
154 } |
|
155 |
|
156 // Check to see if this item was previously selected, if so, unselect it |
|
157 if (iIndex != -1) { |
|
158 this.s = false; |
|
159 jQuery(this).removeClass(jQuery.selectdrug.f.sc); |
|
160 } |
|
161 } else if ( |
|
162 (this.s == true) && |
|
163 (iIndex == -1) |
|
164 ) { |
|
165 // If the item was marked as selected, but it was not selected when you started dragging unselect it. |
|
166 this.s = false; |
|
167 jQuery(this).removeClass(jQuery.selectdrug.f.sc); |
|
168 } else if ( |
|
169 (!this.s) && |
|
170 (jQuery.selectKeyHelper == true) && |
|
171 (iIndex != -1) |
|
172 ) { |
|
173 // Reselect the item if: |
|
174 // - we ARE multiselecting, |
|
175 // - dragged over an allready selected object (so it got unselected) |
|
176 // - But then dragged the selection out of it again. |
|
177 this.s = true; |
|
178 jQuery(this).addClass(jQuery.selectdrug.f.sc); |
|
179 } |
|
180 } |
|
181 ); |
|
182 return false; |
|
183 }; |
|
184 jQuery.selectstop = function(e) |
|
185 { |
|
186 if(!jQuery.selectdrug) |
|
187 return; |
|
188 jQuery.selectstopApply.apply(jQuery.selectdrug, [e]); |
|
189 }; |
|
190 jQuery.selectstopApply = function(e) |
|
191 { |
|
192 jQuery(document) |
|
193 .unbind('mousemove', jQuery.selectcheck) |
|
194 .unbind('mouseup', jQuery.selectstop); |
|
195 if(!jQuery.selectdrug) |
|
196 return; |
|
197 jQuery.selectHelper.css('display','none'); |
|
198 if (this.f.hc) |
|
199 jQuery.selectHelper.removeClass(this.f.hc); |
|
200 jQuery.selectdrug = false; |
|
201 jQuery('body').append(jQuery.selectHelper.get(0)); |
|
202 // |
|
203 // In case we have selected some new items.. |
|
204 if (jQuery.selectedone == true) { |
|
205 if (this.f.onselect) |
|
206 this.f.onselect(jQuery.Selectserialize(jQuery.attr(this,'id'))); |
|
207 } else { |
|
208 if (this.f.onselectstop) |
|
209 this.f.onselectstop(jQuery.Selectserialize(jQuery.attr(this,'id'))); |
|
210 } |
|
211 // Reset current selection |
|
212 jQuery.selectCurrent = []; |
|
213 }; |
|
214 |
|
215 jQuery.Selectserialize = function(s) |
|
216 { |
|
217 var h = ''; |
|
218 var o = []; |
|
219 if (a = jQuery('#' + s)) { |
|
220 a.get(0).f.el.each( |
|
221 function () |
|
222 { |
|
223 if (this.s == true) { |
|
224 if (h.length > 0) { |
|
225 h += '&'; |
|
226 } |
|
227 h += s + '[]=' + jQuery.attr(this,'id'); |
|
228 o[o.length] = jQuery.attr(this,'id'); |
|
229 } |
|
230 } |
|
231 ); |
|
232 } |
|
233 return {hash:h, o:o}; |
|
234 }; |
|
235 jQuery.fn.Selectable = function(o) |
|
236 { |
|
237 if (!jQuery.selectHelper) { |
|
238 jQuery('body',document).append('<div id="selectHelper"></div>').bind('keydown', jQuery.selectKeyDown).bind('keyup', jQuery.selectKeyUp); |
|
239 jQuery.selectHelper = jQuery('#selectHelper'); |
|
240 jQuery.selectHelper.css( |
|
241 { |
|
242 position: 'absolute', |
|
243 display: 'none' |
|
244 } |
|
245 ); |
|
246 |
|
247 if (window.event) { |
|
248 jQuery('body',document).bind('keydown', jQuery.selectKeyDown).bind('keyup', jQuery.selectKeyUp); |
|
249 } else { |
|
250 jQuery(document).bind('keydown', jQuery.selectKeyDown).bind('keyup', jQuery.selectKeyUp); |
|
251 } |
|
252 } |
|
253 |
|
254 if (!o) { |
|
255 o = {}; |
|
256 } |
|
257 return this.each( |
|
258 function() |
|
259 { |
|
260 if (this.isSelectable) |
|
261 return; |
|
262 this.isSelectable = true; |
|
263 this.f = { |
|
264 a : o.accept, |
|
265 o : o.opacity ? parseFloat(o.opacity) : false, |
|
266 sc : o.selectedclass ? o.selectedclass : false, |
|
267 hc : o.helperclass ? o.helperclass : false, |
|
268 onselect : o.onselect ? o.onselect : false, |
|
269 onselectstop : o.onselectstop ? o.onselectstop : false |
|
270 }; |
|
271 this.f.el = jQuery('.' + o.accept); |
|
272 jQuery(this).bind('mousedown', jQuery.selectstart).css('position', 'relative'); |
|
273 } |
|
274 ); |
|
275 }; |
|