3 * jQuery UI Selectable 1.8.2
5 * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)
6 * Dual licensed under the MIT (MIT-LICENSE.txt)
7 * and GPL (GPL-LICENSE.txt) licenses.
9 * http://docs.jquery.com/UI/Selectables
18 $.widget("ui.selectable", $.ui
.mouse
, {
29 this.element
.addClass("ui-selectable");
33 // cache selectee children based on filter
35 this.refresh = function() {
36 selectees
= $(self
.options
.filter
, self
.element
[0]);
37 selectees
.each(function() {
39 var pos
= $this.offset();
40 $.data(this, "selectable-item", {
45 right
: pos
.left
+ $this.outerWidth(),
46 bottom
: pos
.top
+ $this.outerHeight(),
48 selected
: $this.hasClass('ui-selected'),
49 selecting
: $this.hasClass('ui-selecting'),
50 unselecting
: $this.hasClass('ui-unselecting')
56 this.selectees
= selectees
.addClass("ui-selectee");
60 this.helper
= $("<div class='ui-selectable-helper'></div>");
65 .removeClass("ui-selectee")
66 .removeData("selectable-item");
68 .removeClass("ui-selectable ui-selectable-disabled")
69 .removeData("selectable")
70 .unbind(".selectable");
76 _mouseStart: function(event
) {
79 this.opos
= [event
.pageX
, event
.pageY
];
81 if (this.options
.disabled
)
84 var options
= this.options
;
86 this.selectees
= $(options
.filter
, this.element
[0]);
88 this._trigger("start", event
);
90 $(options
.appendTo
).append(this.helper
);
91 // position helper (lasso)
94 "position": "absolute",
95 "left": event
.clientX
,
101 if (options
.autoRefresh
) {
105 this.selectees
.filter('.ui-selected').each(function() {
106 var selectee
= $.data(this, "selectable-item");
107 selectee
.startselected
= true;
108 if (!event
.metaKey
) {
109 selectee
.$element
.removeClass('ui-selected');
110 selectee
.selected
= false;
111 selectee
.$element
.addClass('ui-unselecting');
112 selectee
.unselecting
= true;
113 // selectable UNSELECTING callback
114 self
._trigger("unselecting", event
, {
115 unselecting
: selectee
.element
120 $(event
.target
).parents().andSelf().each(function() {
121 var selectee
= $.data(this, "selectable-item");
123 var doSelect
= !event
.metaKey
|| !selectee
.$element
.hasClass('ui-selected');
125 .removeClass(doSelect
? "ui-unselecting" : "ui-selected")
126 .addClass(doSelect
? "ui-selecting" : "ui-unselecting");
127 selectee
.unselecting
= !doSelect
;
128 selectee
.selecting
= doSelect
;
129 selectee
.selected
= doSelect
;
130 // selectable (UN)SELECTING callback
132 self
._trigger("selecting", event
, {
133 selecting
: selectee
.element
136 self
._trigger("unselecting", event
, {
137 unselecting
: selectee
.element
146 _mouseDrag: function(event
) {
150 if (this.options
.disabled
)
153 var options
= this.options
;
155 var x1
= this.opos
[0], y1
= this.opos
[1], x2
= event
.pageX
, y2
= event
.pageY
;
156 if (x1
> x2
) { var tmp
= x2
; x2
= x1
; x1
= tmp
; }
157 if (y1
> y2
) { var tmp
= y2
; y2
= y1
; y1
= tmp
; }
158 this.helper
.css({left
: x1
, top
: y1
, width
: x2
-x1
, height
: y2
-y1
});
160 this.selectees
.each(function() {
161 var selectee
= $.data(this, "selectable-item");
162 //prevent helper from being selected if appendTo: selectable
163 if (!selectee
|| selectee
.element
== self
.element
[0])
166 if (options
.tolerance
== 'touch') {
167 hit
= ( !(selectee
.left
> x2
|| selectee
.right
< x1
|| selectee
.top
> y2
|| selectee
.bottom
< y1
) );
168 } else if (options
.tolerance
== 'fit') {
169 hit
= (selectee
.left
> x1
&& selectee
.right
< x2
&& selectee
.top
> y1
&& selectee
.bottom
< y2
);
174 if (selectee
.selected
) {
175 selectee
.$element
.removeClass('ui-selected');
176 selectee
.selected
= false;
178 if (selectee
.unselecting
) {
179 selectee
.$element
.removeClass('ui-unselecting');
180 selectee
.unselecting
= false;
182 if (!selectee
.selecting
) {
183 selectee
.$element
.addClass('ui-selecting');
184 selectee
.selecting
= true;
185 // selectable SELECTING callback
186 self
._trigger("selecting", event
, {
187 selecting
: selectee
.element
192 if (selectee
.selecting
) {
193 if (event
.metaKey
&& selectee
.startselected
) {
194 selectee
.$element
.removeClass('ui-selecting');
195 selectee
.selecting
= false;
196 selectee
.$element
.addClass('ui-selected');
197 selectee
.selected
= true;
199 selectee
.$element
.removeClass('ui-selecting');
200 selectee
.selecting
= false;
201 if (selectee
.startselected
) {
202 selectee
.$element
.addClass('ui-unselecting');
203 selectee
.unselecting
= true;
205 // selectable UNSELECTING callback
206 self
._trigger("unselecting", event
, {
207 unselecting
: selectee
.element
211 if (selectee
.selected
) {
212 if (!event
.metaKey
&& !selectee
.startselected
) {
213 selectee
.$element
.removeClass('ui-selected');
214 selectee
.selected
= false;
216 selectee
.$element
.addClass('ui-unselecting');
217 selectee
.unselecting
= true;
218 // selectable UNSELECTING callback
219 self
._trigger("unselecting", event
, {
220 unselecting
: selectee
.element
230 _mouseStop: function(event
) {
233 this.dragged
= false;
235 var options
= this.options
;
237 $('.ui-unselecting', this.element
[0]).each(function() {
238 var selectee
= $.data(this, "selectable-item");
239 selectee
.$element
.removeClass('ui-unselecting');
240 selectee
.unselecting
= false;
241 selectee
.startselected
= false;
242 self
._trigger("unselected", event
, {
243 unselected
: selectee
.element
246 $('.ui-selecting', this.element
[0]).each(function() {
247 var selectee
= $.data(this, "selectable-item");
248 selectee
.$element
.removeClass('ui-selecting').addClass('ui-selected');
249 selectee
.selecting
= false;
250 selectee
.selected
= true;
251 selectee
.startselected
= true;
252 self
._trigger("selected", event
, {
253 selected
: selectee
.element
256 this._trigger("stop", event
);
258 this.helper
.remove();
265 $.extend($.ui
.selectable
, {