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, {