2 * jQuery UI Selectable 1.12.1
5 * Copyright jQuery Foundation and other contributors
6 * Released under the MIT license.
7 * http://jquery.org/license
11 //>>group: Interactions
12 //>>description: Allows groups of elements to be selected with the mouse.
13 //>>docs: http://api.jqueryui.com/selectable/
14 //>>demos: http://jqueryui.com/selectable/
15 //>>css.structure: ../../themes/base/selectable.css
17 ( function( factory ) {
18 if ( typeof define === "function" && define.amd ) {
20 // AMD. Register as an anonymous module.
34 return $.widget( "ui.selectable", $.ui.mouse, {
54 this._addClass( "ui-selectable" );
58 // Cache selectee children based on filter
59 this.refresh = function() {
60 that.elementPos = $( that.element[ 0 ] ).offset();
61 that.selectees = $( that.options.filter, that.element[ 0 ] );
62 that._addClass( that.selectees, "ui-selectee" );
63 that.selectees.each( function() {
64 var $this = $( this ),
65 selecteeOffset = $this.offset(),
67 left: selecteeOffset.left - that.elementPos.left,
68 top: selecteeOffset.top - that.elementPos.top
70 $.data( this, "selectable-item", {
75 right: pos.left + $this.outerWidth(),
76 bottom: pos.top + $this.outerHeight(),
78 selected: $this.hasClass( "ui-selected" ),
79 selecting: $this.hasClass( "ui-selecting" ),
80 unselecting: $this.hasClass( "ui-unselecting" )
88 this.helper = $( "<div>" );
89 this._addClass( this.helper, "ui-selectable-helper" );
92 _destroy: function() {
93 this.selectees.removeData( "selectable-item" );
97 _mouseStart: function( event ) {
99 options = this.options;
101 this.opos = [ event.pageX, event.pageY ];
102 this.elementPos = $( this.element[ 0 ] ).offset();
104 if ( this.options.disabled ) {
108 this.selectees = $( options.filter, this.element[ 0 ] );
110 this._trigger( "start", event );
112 $( options.appendTo ).append( this.helper );
114 // position helper (lasso)
122 if ( options.autoRefresh ) {
126 this.selectees.filter( ".ui-selected" ).each( function() {
127 var selectee = $.data( this, "selectable-item" );
128 selectee.startselected = true;
129 if ( !event.metaKey && !event.ctrlKey ) {
130 that._removeClass( selectee.$element, "ui-selected" );
131 selectee.selected = false;
132 that._addClass( selectee.$element, "ui-unselecting" );
133 selectee.unselecting = true;
135 // selectable UNSELECTING callback
136 that._trigger( "unselecting", event, {
137 unselecting: selectee.element
142 $( event.target ).parents().addBack().each( function() {
144 selectee = $.data( this, "selectable-item" );
146 doSelect = ( !event.metaKey && !event.ctrlKey ) ||
147 !selectee.$element.hasClass( "ui-selected" );
148 that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
149 ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
150 selectee.unselecting = !doSelect;
151 selectee.selecting = doSelect;
152 selectee.selected = doSelect;
154 // selectable (UN)SELECTING callback
156 that._trigger( "selecting", event, {
157 selecting: selectee.element
160 that._trigger( "unselecting", event, {
161 unselecting: selectee.element
170 _mouseDrag: function( event ) {
174 if ( this.options.disabled ) {
180 options = this.options,
186 if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
187 if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
188 this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
190 this.selectees.each( function() {
191 var selectee = $.data( this, "selectable-item" ),
195 //prevent helper from being selected if appendTo: selectable
196 if ( !selectee || selectee.element === that.element[ 0 ] ) {
200 offset.left = selectee.left + that.elementPos.left;
201 offset.right = selectee.right + that.elementPos.left;
202 offset.top = selectee.top + that.elementPos.top;
203 offset.bottom = selectee.bottom + that.elementPos.top;
205 if ( options.tolerance === "touch" ) {
206 hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
207 offset.bottom < y1 ) );
208 } else if ( options.tolerance === "fit" ) {
209 hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
210 offset.bottom < y2 );
216 if ( selectee.selected ) {
217 that._removeClass( selectee.$element, "ui-selected" );
218 selectee.selected = false;
220 if ( selectee.unselecting ) {
221 that._removeClass( selectee.$element, "ui-unselecting" );
222 selectee.unselecting = false;
224 if ( !selectee.selecting ) {
225 that._addClass( selectee.$element, "ui-selecting" );
226 selectee.selecting = true;
228 // selectable SELECTING callback
229 that._trigger( "selecting", event, {
230 selecting: selectee.element
236 if ( selectee.selecting ) {
237 if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
238 that._removeClass( selectee.$element, "ui-selecting" );
239 selectee.selecting = false;
240 that._addClass( selectee.$element, "ui-selected" );
241 selectee.selected = true;
243 that._removeClass( selectee.$element, "ui-selecting" );
244 selectee.selecting = false;
245 if ( selectee.startselected ) {
246 that._addClass( selectee.$element, "ui-unselecting" );
247 selectee.unselecting = true;
250 // selectable UNSELECTING callback
251 that._trigger( "unselecting", event, {
252 unselecting: selectee.element
256 if ( selectee.selected ) {
257 if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
258 that._removeClass( selectee.$element, "ui-selected" );
259 selectee.selected = false;
261 that._addClass( selectee.$element, "ui-unselecting" );
262 selectee.unselecting = true;
264 // selectable UNSELECTING callback
265 that._trigger( "unselecting", event, {
266 unselecting: selectee.element
276 _mouseStop: function( event ) {
279 this.dragged = false;
281 $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
282 var selectee = $.data( this, "selectable-item" );
283 that._removeClass( selectee.$element, "ui-unselecting" );
284 selectee.unselecting = false;
285 selectee.startselected = false;
286 that._trigger( "unselected", event, {
287 unselected: selectee.element
290 $( ".ui-selecting", this.element[ 0 ] ).each( function() {
291 var selectee = $.data( this, "selectable-item" );
292 that._removeClass( selectee.$element, "ui-selecting" )
293 ._addClass( selectee.$element, "ui-selected" );
294 selectee.selecting = false;
295 selectee.selected = true;
296 selectee.startselected = true;
297 that._trigger( "selected", event, {
298 selected: selectee.element
301 this._trigger( "stop", event );
303 this.helper.remove();