暫無描述

selectable.js 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*!
  2. * jQuery UI Selectable 1.12.1
  3. * http://jqueryui.com
  4. *
  5. * Copyright jQuery Foundation and other contributors
  6. * Released under the MIT license.
  7. * http://jquery.org/license
  8. */
  9. //>>label: Selectable
  10. //>>group: Interactions
  11. //>>description: Allows groups of elements to be selected with the mouse.
  12. //>>docs: http://api.jqueryui.com/selectable/
  13. //>>demos: http://jqueryui.com/selectable/
  14. //>>css.structure: ../../themes/base/selectable.css
  15. ( function( factory ) {
  16. if ( typeof define === "function" && define.amd ) {
  17. // AMD. Register as an anonymous module.
  18. define( [
  19. "jquery",
  20. "./mouse",
  21. "./core"
  22. ], factory );
  23. } else {
  24. // Browser globals
  25. factory( jQuery );
  26. }
  27. }( function( $ ) {
  28. return $.widget( "ui.selectable", $.ui.mouse, {
  29. version: "1.12.1",
  30. options: {
  31. appendTo: "body",
  32. autoRefresh: true,
  33. distance: 0,
  34. filter: "*",
  35. tolerance: "touch",
  36. // Callbacks
  37. selected: null,
  38. selecting: null,
  39. start: null,
  40. stop: null,
  41. unselected: null,
  42. unselecting: null
  43. },
  44. _create: function() {
  45. var that = this;
  46. this._addClass( "ui-selectable" );
  47. this.dragged = false;
  48. // Cache selectee children based on filter
  49. this.refresh = function() {
  50. that.elementPos = $( that.element[ 0 ] ).offset();
  51. that.selectees = $( that.options.filter, that.element[ 0 ] );
  52. that._addClass( that.selectees, "ui-selectee" );
  53. that.selectees.each( function() {
  54. var $this = $( this ),
  55. selecteeOffset = $this.offset(),
  56. pos = {
  57. left: selecteeOffset.left - that.elementPos.left,
  58. top: selecteeOffset.top - that.elementPos.top
  59. };
  60. $.data( this, "selectable-item", {
  61. element: this,
  62. $element: $this,
  63. left: pos.left,
  64. top: pos.top,
  65. right: pos.left + $this.outerWidth(),
  66. bottom: pos.top + $this.outerHeight(),
  67. startselected: false,
  68. selected: $this.hasClass( "ui-selected" ),
  69. selecting: $this.hasClass( "ui-selecting" ),
  70. unselecting: $this.hasClass( "ui-unselecting" )
  71. } );
  72. } );
  73. };
  74. this.refresh();
  75. this._mouseInit();
  76. this.helper = $( "<div>" );
  77. this._addClass( this.helper, "ui-selectable-helper" );
  78. },
  79. _destroy: function() {
  80. this.selectees.removeData( "selectable-item" );
  81. this._mouseDestroy();
  82. },
  83. _mouseStart: function( event ) {
  84. var that = this,
  85. options = this.options;
  86. this.opos = [ event.pageX, event.pageY ];
  87. this.elementPos = $( this.element[ 0 ] ).offset();
  88. if ( this.options.disabled ) {
  89. return;
  90. }
  91. this.selectees = $( options.filter, this.element[ 0 ] );
  92. this._trigger( "start", event );
  93. $( options.appendTo ).append( this.helper );
  94. // position helper (lasso)
  95. this.helper.css( {
  96. "left": event.pageX,
  97. "top": event.pageY,
  98. "width": 0,
  99. "height": 0
  100. } );
  101. if ( options.autoRefresh ) {
  102. this.refresh();
  103. }
  104. this.selectees.filter( ".ui-selected" ).each( function() {
  105. var selectee = $.data( this, "selectable-item" );
  106. selectee.startselected = true;
  107. if ( !event.metaKey && !event.ctrlKey ) {
  108. that._removeClass( selectee.$element, "ui-selected" );
  109. selectee.selected = false;
  110. that._addClass( selectee.$element, "ui-unselecting" );
  111. selectee.unselecting = true;
  112. // selectable UNSELECTING callback
  113. that._trigger( "unselecting", event, {
  114. unselecting: selectee.element
  115. } );
  116. }
  117. } );
  118. $( event.target ).parents().addBack().each( function() {
  119. var doSelect,
  120. selectee = $.data( this, "selectable-item" );
  121. if ( selectee ) {
  122. doSelect = ( !event.metaKey && !event.ctrlKey ) ||
  123. !selectee.$element.hasClass( "ui-selected" );
  124. that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
  125. ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
  126. selectee.unselecting = !doSelect;
  127. selectee.selecting = doSelect;
  128. selectee.selected = doSelect;
  129. // selectable (UN)SELECTING callback
  130. if ( doSelect ) {
  131. that._trigger( "selecting", event, {
  132. selecting: selectee.element
  133. } );
  134. } else {
  135. that._trigger( "unselecting", event, {
  136. unselecting: selectee.element
  137. } );
  138. }
  139. return false;
  140. }
  141. } );
  142. },
  143. _mouseDrag: function( event ) {
  144. this.dragged = true;
  145. if ( this.options.disabled ) {
  146. return;
  147. }
  148. var tmp,
  149. that = this,
  150. options = this.options,
  151. x1 = this.opos[ 0 ],
  152. y1 = this.opos[ 1 ],
  153. x2 = event.pageX,
  154. y2 = event.pageY;
  155. if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
  156. if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
  157. this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
  158. this.selectees.each( function() {
  159. var selectee = $.data( this, "selectable-item" ),
  160. hit = false,
  161. offset = {};
  162. //prevent helper from being selected if appendTo: selectable
  163. if ( !selectee || selectee.element === that.element[ 0 ] ) {
  164. return;
  165. }
  166. offset.left = selectee.left + that.elementPos.left;
  167. offset.right = selectee.right + that.elementPos.left;
  168. offset.top = selectee.top + that.elementPos.top;
  169. offset.bottom = selectee.bottom + that.elementPos.top;
  170. if ( options.tolerance === "touch" ) {
  171. hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
  172. offset.bottom < y1 ) );
  173. } else if ( options.tolerance === "fit" ) {
  174. hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
  175. offset.bottom < y2 );
  176. }
  177. if ( hit ) {
  178. // SELECT
  179. if ( selectee.selected ) {
  180. that._removeClass( selectee.$element, "ui-selected" );
  181. selectee.selected = false;
  182. }
  183. if ( selectee.unselecting ) {
  184. that._removeClass( selectee.$element, "ui-unselecting" );
  185. selectee.unselecting = false;
  186. }
  187. if ( !selectee.selecting ) {
  188. that._addClass( selectee.$element, "ui-selecting" );
  189. selectee.selecting = true;
  190. // selectable SELECTING callback
  191. that._trigger( "selecting", event, {
  192. selecting: selectee.element
  193. } );
  194. }
  195. } else {
  196. // UNSELECT
  197. if ( selectee.selecting ) {
  198. if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
  199. that._removeClass( selectee.$element, "ui-selecting" );
  200. selectee.selecting = false;
  201. that._addClass( selectee.$element, "ui-selected" );
  202. selectee.selected = true;
  203. } else {
  204. that._removeClass( selectee.$element, "ui-selecting" );
  205. selectee.selecting = false;
  206. if ( selectee.startselected ) {
  207. that._addClass( selectee.$element, "ui-unselecting" );
  208. selectee.unselecting = true;
  209. }
  210. // selectable UNSELECTING callback
  211. that._trigger( "unselecting", event, {
  212. unselecting: selectee.element
  213. } );
  214. }
  215. }
  216. if ( selectee.selected ) {
  217. if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
  218. that._removeClass( selectee.$element, "ui-selected" );
  219. selectee.selected = false;
  220. that._addClass( selectee.$element, "ui-unselecting" );
  221. selectee.unselecting = true;
  222. // selectable UNSELECTING callback
  223. that._trigger( "unselecting", event, {
  224. unselecting: selectee.element
  225. } );
  226. }
  227. }
  228. }
  229. } );
  230. return false;
  231. },
  232. _mouseStop: function( event ) {
  233. var that = this;
  234. this.dragged = false;
  235. $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
  236. var selectee = $.data( this, "selectable-item" );
  237. that._removeClass( selectee.$element, "ui-unselecting" );
  238. selectee.unselecting = false;
  239. selectee.startselected = false;
  240. that._trigger( "unselected", event, {
  241. unselected: selectee.element
  242. } );
  243. } );
  244. $( ".ui-selecting", this.element[ 0 ] ).each( function() {
  245. var selectee = $.data( this, "selectable-item" );
  246. that._removeClass( selectee.$element, "ui-selecting" )
  247. ._addClass( selectee.$element, "ui-selected" );
  248. selectee.selecting = false;
  249. selectee.selected = true;
  250. selectee.startselected = true;
  251. that._trigger( "selected", event, {
  252. selected: selectee.element
  253. } );
  254. } );
  255. this._trigger( "stop", event );
  256. this.helper.remove();
  257. return false;
  258. }
  259. } );
  260. } ) );