select2.amd.js 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  1. define('select2/utils',[], function () {
  2. var Utils = {};
  3. Utils.Extend = function (ChildClass, SuperClass) {
  4. var __hasProp = {}.hasOwnProperty;
  5. function BaseConstructor () {
  6. this.constructor = ChildClass;
  7. }
  8. for (var key in SuperClass) {
  9. if (__hasProp.call(SuperClass, key)) {
  10. ChildClass[key] = SuperClass[key];
  11. }
  12. }
  13. BaseConstructor.prototype = SuperClass.prototype;
  14. ChildClass.prototype = new BaseConstructor();
  15. ChildClass.__super__ = SuperClass.prototype;
  16. return ChildClass;
  17. };
  18. function getMethods (theClass) {
  19. var proto = theClass.prototype;
  20. var methods = [];
  21. for (var methodName in proto) {
  22. var m = proto[methodName];
  23. if (typeof m !== 'function') {
  24. continue;
  25. }
  26. methods.push(methodName);
  27. }
  28. return methods;
  29. }
  30. Utils.Decorate = function (SuperClass, DecoratorClass) {
  31. var decoratedMethods = getMethods(DecoratorClass);
  32. var superMethods = getMethods(SuperClass);
  33. function DecoratedClass () {
  34. var unshift = Array.prototype.unshift;
  35. var argCount = DecoratorClass.prototype.constructor.length;
  36. var calledConstructor = SuperClass.prototype.constructor;
  37. if (argCount > 0) {
  38. unshift.call(arguments, SuperClass.prototype.constructor);
  39. calledConstructor = DecoratorClass.prototype.constructor;
  40. }
  41. calledConstructor.apply(this, arguments);
  42. }
  43. DecoratorClass.displayName = SuperClass.displayName;
  44. function ctr () {
  45. this.constructor = DecoratedClass;
  46. }
  47. DecoratedClass.prototype = new ctr();
  48. for (var m = 0; m < superMethods.length; m++) {
  49. var superMethod = superMethods[m];
  50. DecoratedClass.prototype[superMethod] =
  51. SuperClass.prototype[superMethod];
  52. }
  53. var calledMethod = function (methodName) {
  54. // Stub out the original method if it's not decorating an actual method
  55. var originalMethod = function () {};
  56. if (methodName in DecoratedClass.prototype) {
  57. originalMethod = DecoratedClass.prototype[methodName];
  58. }
  59. var decoratedMethod = DecoratorClass.prototype[methodName];
  60. return function () {
  61. var unshift = Array.prototype.unshift;
  62. unshift.call(arguments, originalMethod);
  63. return decoratedMethod.apply(this, arguments);
  64. };
  65. };
  66. for (var d = 0; d < decoratedMethods.length; d++) {
  67. var decoratedMethod = decoratedMethods[d];
  68. DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
  69. }
  70. return DecoratedClass;
  71. };
  72. var Observable = function () {
  73. this.listeners = {};
  74. };
  75. Observable.prototype.on = function (event, callback) {
  76. if (event in this.listeners) {
  77. this.listeners[event].push(callback);
  78. } else {
  79. this.listeners[event] = [callback];
  80. }
  81. };
  82. Observable.prototype.trigger = function (event) {
  83. var slice = Array.prototype.slice;
  84. if (event in this.listeners) {
  85. this.invoke(this.listeners[event], slice.call(arguments, 1));
  86. }
  87. if ('*' in this.listeners) {
  88. this.invoke(this.listeners['*'], arguments);
  89. }
  90. };
  91. Observable.prototype.invoke = function (listeners, params) {
  92. for (var i = 0, len = listeners.length; i < len; i++) {
  93. listeners[i].apply(this, params);
  94. }
  95. };
  96. Utils.Observable = Observable;
  97. return Utils;
  98. });
  99. define('select2/results',[
  100. './utils'
  101. ], function (Utils) {
  102. function Results ($element, options, dataAdapter) {
  103. this.$element = $element;
  104. this.data = dataAdapter;
  105. Results.__super__.constructor.call(this);
  106. }
  107. Utils.Extend(Results, Utils.Observable);
  108. Results.prototype.render = function () {
  109. var $results = $(
  110. '<ul class="options"></ul>'
  111. );
  112. this.$results = $results;
  113. return $results;
  114. };
  115. Results.prototype.clear = function () {
  116. this.$results.empty();
  117. };
  118. Results.prototype.append = function (data) {
  119. var $options = [];
  120. data = this.sort(data);
  121. for (var d = 0; d < data.length; d++) {
  122. var item = data[d];
  123. var $option = this.option(item);
  124. $options.push($option);
  125. }
  126. this.$results.append($options);
  127. };
  128. Results.prototype.sort = function (data) {
  129. return data;
  130. };
  131. Results.prototype.setClasses = function () {
  132. var self = this;
  133. this.data.current(function (selected) {
  134. var selectedIds = $.map(selected, function (s) {
  135. return s.id.toString();
  136. });
  137. self.$results.find('.option.selected').removeClass('selected');
  138. var $options = self.$results.find('.option');
  139. $options.each(function () {
  140. var $option = $(this);
  141. var item = $option.data('data');
  142. if (item.id != null && selectedIds.indexOf(item.id.toString()) > -1) {
  143. $option.addClass('selected');
  144. }
  145. });
  146. });
  147. };
  148. Results.prototype.option = function (data) {
  149. var $option = $(
  150. '<li class="option highlightable selectable"></li>'
  151. );
  152. if (data.children) {
  153. $option.addClass('group').removeClass('highlightable selectable');
  154. var $label = $('<strong class="group-label"></strong>');
  155. $label.html(data.text);
  156. var $children = [];
  157. for (var c = 0; c < data.children.length; c++) {
  158. var child = data.children[c];
  159. var $child = this.option(child);
  160. $children.push($child);
  161. }
  162. var $childrenContainer = $('<ul class="options nested-options"></ul>');
  163. $childrenContainer.append($children);
  164. $option.append($label);
  165. $option.append($childrenContainer);
  166. } else {
  167. $option.html(data.text);
  168. }
  169. if (data.disabled) {
  170. $option.removeClass('selectable highlightable').addClass('disabled');
  171. }
  172. if (data.id == null) {
  173. $option.removeClass('selectable highlightable');
  174. }
  175. $option.data('data', data);
  176. return $option;
  177. };
  178. Results.prototype.bind = function (container, $container) {
  179. var self = this;
  180. container.on('results:all', function (params) {
  181. self.clear();
  182. self.append(params.data);
  183. self.setClasses();
  184. });
  185. container.on('results:append', function (params) {
  186. self.append(params.data);
  187. self.setClasses();
  188. });
  189. container.on('select', function () {
  190. self.setClasses();
  191. });
  192. container.on('unselect', function () {
  193. self.setClasses();
  194. });
  195. this.$results.on('mouseup', '.option.selectable', function (evt) {
  196. var $this = $(this);
  197. var data = $this.data('data');
  198. if ($this.hasClass('selected')) {
  199. self.trigger('unselected', {
  200. originalEvent: evt,
  201. data: data
  202. });
  203. return;
  204. }
  205. self.trigger('selected', {
  206. originalEvent: evt,
  207. data: data
  208. });
  209. });
  210. this.$results.on('mouseenter', '.option.highlightable', function (evt) {
  211. self.$results.find('.option.highlighted').removeClass('highlighted');
  212. $(this).addClass('highlighted');
  213. });
  214. this.$results.on('mouseleave', '.option', function (evt) {
  215. $(this).removeClass('highlighted');
  216. });
  217. };
  218. return Results;
  219. });
  220. define('select2/selection/base',[
  221. '../utils'
  222. ], function (Utils) {
  223. function BaseSelection ($element, options) {
  224. this.$element = $element;
  225. this.options = options;
  226. BaseSelection.__super__.constructor.call(this);
  227. }
  228. Utils.Extend(BaseSelection, Utils.Observable);
  229. BaseSelection.prototype.render = function () {
  230. throw new Error('The `render` method must be defined in child classes.');
  231. };
  232. BaseSelection.prototype.bind = function (container, $container) {
  233. var self = this;
  234. container.on('selection:update', function (params) {
  235. self.update(params.data);
  236. });
  237. };
  238. BaseSelection.prototype.update = function (data) {
  239. throw new Error('The `update` method must be defined in child classes.');
  240. };
  241. return BaseSelection;
  242. });
  243. define('select2/selection/single',[
  244. './base',
  245. '../utils'
  246. ], function (BaseSelection, Utils) {
  247. function SingleSelection () {
  248. SingleSelection.__super__.constructor.apply(this, arguments);
  249. }
  250. Utils.Extend(SingleSelection, BaseSelection);
  251. SingleSelection.prototype.render = function () {
  252. var $selection = $(
  253. '<span class="single-select">' +
  254. '<span class="rendered-selection"></span>' +
  255. '</span>'
  256. );
  257. this.$selection = $selection;
  258. return $selection;
  259. };
  260. SingleSelection.prototype.bind = function (container, $container) {
  261. var self = this;
  262. SingleSelection.__super__.bind.apply(this, arguments);
  263. this.$selection.on('mousedown', function (evt) {
  264. // Only respond to left clicks
  265. if (evt.which !== 1) {
  266. return;
  267. }
  268. self.trigger('toggle', {
  269. originalEvent: evt
  270. });
  271. });
  272. container.on('selection:update', function (params) {
  273. self.update(params.data);
  274. });
  275. };
  276. SingleSelection.prototype.clear = function () {
  277. this.$selection.find('.rendered-selection').empty();
  278. };
  279. SingleSelection.prototype.display = function (data) {
  280. return data.text;
  281. };
  282. SingleSelection.prototype.selectionContainer = function () {
  283. return $('<span></span>');
  284. };
  285. SingleSelection.prototype.update = function (data) {
  286. if (data.length === 0) {
  287. this.clear();
  288. return;
  289. }
  290. var selection = data[0];
  291. var formatted = this.display(selection);
  292. this.$selection.find('.rendered-selection').html(formatted);
  293. };
  294. return SingleSelection;
  295. });
  296. define('select2/selection/multiple',[
  297. './base',
  298. '../utils'
  299. ], function (BaseSelection, Utils) {
  300. function MultipleSelection ($element, options) {
  301. this.$element = $element;
  302. this.options = options;
  303. MultipleSelection.__super__.constructor.call(this);
  304. }
  305. Utils.Extend(MultipleSelection, BaseSelection);
  306. MultipleSelection.prototype.render = function () {
  307. var $selection = $(
  308. '<span class="multiple-select">' +
  309. '<ul class="rendered-selection"></ul>' +
  310. '</span>'
  311. );
  312. this.$selection = $selection;
  313. return $selection;
  314. };
  315. MultipleSelection.prototype.bind = function (container, $container) {
  316. var self = this;
  317. MultipleSelection.__super__.bind.apply(this, arguments);
  318. this.$selection.on('click', function (evt) {
  319. self.trigger('toggle', {
  320. originalEvent: evt
  321. });
  322. });
  323. this.$selection.on('click', '.remove', function (evt) {
  324. var $remove = $(this);
  325. var $selection = $remove.parent();
  326. var data = $selection.data('data');
  327. self.trigger('unselected', {
  328. originalEvent: evt,
  329. data: data
  330. });
  331. });
  332. };
  333. MultipleSelection.prototype.clear = function () {
  334. this.$selection.find('.rendered-selection').empty();
  335. };
  336. MultipleSelection.prototype.display = function (data) {
  337. return data.text;
  338. };
  339. MultipleSelection.prototype.selectionContainer = function () {
  340. var $container = $(
  341. '<li class="choice">' +
  342. '<span class="remove">&times;</span>' +
  343. '</li>'
  344. );
  345. return $container;
  346. };
  347. MultipleSelection.prototype.update = function (data) {
  348. this.clear();
  349. if (data.length === 0) {
  350. return;
  351. }
  352. var $selections = [];
  353. for (var d = 0; d < data.length; d++) {
  354. var selection = data[d];
  355. var formatted = this.display(selection);
  356. var $selection = this.selectionContainer();
  357. $selection.append(formatted);
  358. $selection.data('data', selection);
  359. $selections.push($selection);
  360. }
  361. this.$selection.find('.rendered-selection').append($selections);
  362. };
  363. return MultipleSelection;
  364. });
  365. define('select2/selection/placeholder',[
  366. '../utils'
  367. ], function (Utils) {
  368. function Placeholder (decorated, $element, options) {
  369. this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
  370. decorated.call(this, $element, options);
  371. }
  372. Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
  373. if (typeof placeholder === 'string') {
  374. placeholder = {
  375. id: '',
  376. text: placeholder
  377. };
  378. }
  379. return placeholder;
  380. };
  381. Placeholder.prototype.update = function (decorated, data) {
  382. var singlePlaceholder = (
  383. data.length == 1 && data[0].id != this.placeholder.id
  384. );
  385. var multipleSelections = data.length > 1;
  386. if (multipleSelections || singlePlaceholder) {
  387. return decorated.call(this, data);
  388. }
  389. this.clear();
  390. var $placeholder = this.selectionContainer();
  391. $placeholder.html(this.display(this.placeholder));
  392. $placeholder.addClass('placeholder').removeClass('choice');
  393. this.$selection.find('.rendered-selection').append($placeholder);
  394. };
  395. return Placeholder;
  396. });
  397. define('select2/data/base',[
  398. '../utils'
  399. ], function (Utils) {
  400. function BaseAdapter ($element, options) {
  401. BaseAdapter.__super__.constructor.call(this);
  402. }
  403. Utils.Extend(BaseAdapter, Utils.Observable);
  404. BaseAdapter.prototype.current = function (callback) {
  405. throw new Error('The `current` method must be defined in child classes.');
  406. };
  407. BaseAdapter.prototype.query = function (params, callback) {
  408. throw new Error('The `query` method must be defined in child classes.');
  409. };
  410. BaseAdapter.prototype.bind = function (container, $container) {
  411. // Can be implemented in subclasses
  412. };
  413. return BaseAdapter;
  414. });
  415. define('select2/data/select',[
  416. './base',
  417. '../utils',
  418. 'jquery'
  419. ], function (BaseAdapter, Utils, $) {
  420. function SelectAdapter ($element, options) {
  421. this.$element = $element;
  422. SelectAdapter.__super__.constructor.call(this);
  423. }
  424. Utils.Extend(SelectAdapter, BaseAdapter);
  425. SelectAdapter.prototype.current = function (callback) {
  426. var data = [];
  427. var self = this;
  428. this.$element.find(':selected').each(function () {
  429. var $option = $(this);
  430. var option = self.item($option);
  431. data.push(option);
  432. });
  433. callback(data);
  434. };
  435. SelectAdapter.prototype.select = function (data) {
  436. var self = this;
  437. if (this.$element.prop('multiple')) {
  438. this.current(function (currentData) {
  439. var val = [];
  440. data = [data];
  441. data.push.apply(data, currentData);
  442. for (var d = 0; d < data.length; d++) {
  443. id = data[d].id;
  444. if (val.indexOf(id) === -1) {
  445. val.push(id);
  446. }
  447. }
  448. self.$element.val(val);
  449. self.$element.trigger('change');
  450. });
  451. } else {
  452. var val = data.id;
  453. this.$element.val(val);
  454. this.$element.trigger('change');
  455. }
  456. };
  457. SelectAdapter.prototype.unselect = function (data) {
  458. var self = this;
  459. if (!this.$element.prop('multiple')) {
  460. return;
  461. }
  462. this.current(function (currentData) {
  463. var val = [];
  464. for (var d = 0; d < currentData.length; d++) {
  465. id = currentData[d].id;
  466. if (id !== data.id && val.indexOf(id) === -1) {
  467. val.push(id);
  468. }
  469. }
  470. self.$element.val(val);
  471. self.$element.trigger('change');
  472. });
  473. };
  474. SelectAdapter.prototype.bind = function (container, $container) {
  475. var self = this;
  476. container.on('select', function (params) {
  477. self.select(params.data);
  478. });
  479. container.on('unselect', function (params) {
  480. self.unselect(params.data);
  481. });
  482. };
  483. SelectAdapter.prototype.query = function (params, callback) {
  484. var data = [];
  485. var self = this;
  486. var $options = this.$element.children();
  487. $options.each(function () {
  488. var $option = $(this);
  489. if (!$option.is('option') && !$option.is('optgroup')) {
  490. return;
  491. }
  492. var option = self.item($option);
  493. var matches = self.matches(params, option);
  494. if (matches !== null) {
  495. data.push(matches);
  496. }
  497. });
  498. callback(data);
  499. };
  500. SelectAdapter.prototype.item = function ($option) {
  501. var data = $option.data('data');
  502. // If the data has already be generated, use it
  503. if (data == null) {
  504. if ($option.is('option')) {
  505. data = {
  506. id: $option.val(),
  507. text: $option.html(),
  508. disabled: $option.prop('disabled')
  509. };
  510. } else if ($option.is('optgroup')) {
  511. data = {
  512. text: $option.attr('label'),
  513. children: []
  514. };
  515. var $children = $option.children('option');
  516. var children = [];
  517. for (var c = 0; c < $children.length; c++) {
  518. var $child = $($children[c]);
  519. var child = this.item($child);
  520. children.push(child);
  521. }
  522. data.children = children;
  523. }
  524. $option.data('data', data);
  525. }
  526. return data;
  527. };
  528. SelectAdapter.prototype.matches = function (params, data) {
  529. var match = $.extend(true, {}, data);
  530. if (data.children) {
  531. for (var c = data.children.length - 1; c >= 0; c--) {
  532. var child = data.children[c];
  533. var matches = this.matches(params, child);
  534. // If there wasn't a match, remove the object in the array
  535. if (matches === null) {
  536. match.children.splice(c, 1);
  537. }
  538. }
  539. if (match.children.length > 0) {
  540. return match;
  541. }
  542. }
  543. if ($.trim(params.term) === '') {
  544. return match;
  545. }
  546. if (data.text.toUpperCase().indexOf(params.term.toUpperCase()) > -1) {
  547. return match;
  548. }
  549. return null;
  550. };
  551. return SelectAdapter;
  552. });
  553. define('select2/data/array',[
  554. './select',
  555. '../utils'
  556. ], function (SelectAdapter, Utils) {
  557. function ArrayAdapter ($element, options) {
  558. this.data = options.options.data;
  559. ArrayAdapter.__super__.constructor.call(this, $element, options);
  560. }
  561. Utils.Extend(ArrayAdapter, SelectAdapter);
  562. ArrayAdapter.prototype.select = function (data) {
  563. var self = this;
  564. this.$element.find('option').each(function () {
  565. var $option = $(this);
  566. var option = self.item($option);
  567. if (option.id == data.id.toString()) {
  568. $option.remove();
  569. }
  570. });
  571. var $option = this.option(data);
  572. this.$element.append($option);
  573. ArrayAdapter.__super__.select.call(this, data);
  574. };
  575. ArrayAdapter.prototype.option = function (data) {
  576. var $option = $('<option></option>');
  577. $option.text(data.text);
  578. $option.val(data.id);
  579. $option.data('data', data);
  580. return $option;
  581. };
  582. ArrayAdapter.prototype.query = function (params, callback) {
  583. var matches = [];
  584. var self = this;
  585. $.each(this.data, function () {
  586. var option = this;
  587. if (self.matches(params, option)) {
  588. matches.push(option);
  589. }
  590. });
  591. callback(matches);
  592. };
  593. return ArrayAdapter;
  594. });
  595. define('select2/data/ajax',[
  596. './array',
  597. '../utils',
  598. 'jquery'
  599. ], function (ArrayAdapter, Utils, $) {
  600. function AjaxAdapter ($element, options) {
  601. this.ajaxOptions = options.get('ajax');
  602. this.processResults = this.ajaxOptions.processResults ||
  603. function (results) {
  604. return results;
  605. };
  606. ArrayAdapter.__super__.constructor.call(this, $element, options);
  607. }
  608. Utils.Extend(AjaxAdapter, ArrayAdapter);
  609. AjaxAdapter.prototype.query = function (params, callback) {
  610. var matches = [];
  611. var self = this;
  612. var options = $.extend({
  613. type: 'GET'
  614. }, this.ajaxOptions);
  615. if (typeof options.url === 'function') {
  616. options.url = options.url(params);
  617. }
  618. if (typeof options.data === 'function') {
  619. options.data = options.data(params);
  620. }
  621. var $request = $.ajax(options);
  622. $request.success(function (data) {
  623. var results = self.processResults(data);
  624. callback(results);
  625. });
  626. };
  627. return AjaxAdapter;
  628. });
  629. define('select2/dropdown',[
  630. './utils'
  631. ], function (Utils) {
  632. function Dropdown ($element, options) {
  633. this.$element = $element;
  634. }
  635. Utils.Extend(Dropdown, Utils.Observable);
  636. Dropdown.prototype.render = function () {
  637. var $dropdown = $(
  638. '<span class="dropdown">' +
  639. '<span class="results"></span>' +
  640. '</span>'
  641. );
  642. return $dropdown;
  643. };
  644. Dropdown.prototype.bind = function (container, $container) {
  645. // Can be implemented in subclasses
  646. };
  647. return Dropdown;
  648. });
  649. define('select2/dropdown/search',[
  650. ], function () {
  651. function Search () { }
  652. Search.prototype.render = function (decorated) {
  653. var $rendered = decorated.call(this);
  654. var $search = $(
  655. '<span class="search">' +
  656. '<input type="search" name="search" />' +
  657. '</span>'
  658. );
  659. this.$searchContainer = $search;
  660. this.$search = $search.find('input');
  661. $rendered.prepend($search);
  662. return $rendered;
  663. };
  664. Search.prototype.bind = function (decorated, container, $container) {
  665. var self = this;
  666. decorated.call(this, container, $container);
  667. this.$search.on('keyup', function () {
  668. container.trigger('query', {
  669. term: $(this).val()
  670. });
  671. });
  672. container.on('results:all', function (params) {
  673. if (params.query.term == null || params.query.term === '') {
  674. var showSearch = self.showSearch(params);
  675. if (showSearch) {
  676. self.$searchContainer.show();
  677. } else {
  678. self.$searchContainer.hide();
  679. }
  680. }
  681. });
  682. };
  683. Search.prototype.showSearch = function (params) {
  684. return true;
  685. };
  686. return Search;
  687. });
  688. define('select2/defaults',[
  689. './results',
  690. './selection/single',
  691. './selection/multiple',
  692. './selection/placeholder',
  693. './utils',
  694. './data/select',
  695. './data/array',
  696. './data/ajax',
  697. './dropdown',
  698. './dropdown/search'
  699. ], function (ResultsList,
  700. SingleSelection, MultipleSelection, Placeholder,
  701. Utils,
  702. SelectData, ArrayData, AjaxData,
  703. Dropdown, Search) {
  704. function Defaults () {
  705. this.reset();
  706. }
  707. Defaults.prototype.apply = function (options) {
  708. options = $.extend({}, options, this.defaults);
  709. if (options.dataAdapter == null) {
  710. if (options.ajax) {
  711. options.dataAdapter = AjaxData;
  712. } else if (options.data) {
  713. options.dataAdapter = ArrayData;
  714. } else {
  715. options.dataAdapter = SelectData;
  716. }
  717. }
  718. if (options.resultsAdapter == null) {
  719. options.resultsAdapter = ResultsList;
  720. }
  721. if (options.dropdownAdapter == null) {
  722. var SearchableDropdown = Utils.Decorate(Dropdown, Search);
  723. options.dropdownAdapter = SearchableDropdown;
  724. }
  725. if (options.selectionAdapter == null) {
  726. if (options.multiple) {
  727. options.selectionAdapter = MultipleSelection;
  728. } else {
  729. options.selectionAdapter = SingleSelection;
  730. }
  731. // Add the placeholder mixin if a placeholder was specified
  732. if (options.placeholder != null) {
  733. options.selectionAdapter = Utils.Decorate(
  734. options.selectionAdapter,
  735. Placeholder
  736. );
  737. }
  738. }
  739. return options;
  740. };
  741. Defaults.prototype.reset = function () {
  742. this.defaults = { };
  743. };
  744. var defaults = new Defaults();
  745. return defaults;
  746. });
  747. define('select2/options',[
  748. './defaults'
  749. ], function (Defaults) {
  750. function Options (options) {
  751. this.options = Defaults.apply(options);
  752. }
  753. Options.prototype.fromElement = function ($e) {
  754. return this;
  755. };
  756. Options.prototype.get = function (key) {
  757. return this.options[key];
  758. };
  759. Options.prototype.set = function (key, val) {
  760. this.options[key] = val;
  761. };
  762. return Options;
  763. });
  764. define('select2/core',[
  765. 'jquery',
  766. './options',
  767. './utils'
  768. ], function ($, Options, Utils) {
  769. var Select2 = function ($element, options) {
  770. this.$element = $element;
  771. options = options || {};
  772. options.multiple = options.multiple || $element.prop('multiple');
  773. this.options = new Options(options);
  774. Select2.__super__.constructor.call(this);
  775. // Set up containers and adapters
  776. var DataAdapter = this.options.get('dataAdapter');
  777. this.data = new DataAdapter($element, this.options);
  778. var $container = this.render();
  779. this.$container = $container;
  780. $container.insertAfter(this.$element);
  781. $container.width($element.outerWidth(false));
  782. var SelectionAdapter = this.options.get('selectionAdapter');
  783. this.selection = new SelectionAdapter($element, this.options);
  784. var $selectionContainer = $container.find('.selection');
  785. var $selection = this.selection.render();
  786. $selectionContainer.append($selection);
  787. var DropdownAdapter = this.options.get('dropdownAdapter');
  788. this.dropdown = new DropdownAdapter($element, this.options);
  789. var $dropdownContainer = $container.find('.dropdown-wrapper');
  790. var $dropdown = this.dropdown.render();
  791. $dropdownContainer.append($dropdown);
  792. var ResultsAdapter = this.options.get('resultsAdapter');
  793. this.results = new ResultsAdapter($element, this.options, this.data);
  794. var $resultsContainer = $dropdown.find('.results');
  795. var $results = this.results.render();
  796. $resultsContainer.append($results);
  797. // Bind events
  798. var self = this;
  799. this.data.bind(this, $container);
  800. this.selection.bind(this, $container);
  801. this.dropdown.bind(this, $container);
  802. this.results.bind(this, $container);
  803. this.$element.on('change', function () {
  804. self.data.current(function (data) {
  805. self.trigger('selection:update', {
  806. data: data
  807. });
  808. });
  809. });
  810. this.selection.on('toggle', function () {
  811. self.toggleDropdown();
  812. });
  813. this.selection.on('unselected', function (params) {
  814. self.trigger('unselect', params);
  815. self.trigger('close');
  816. });
  817. this.results.on('selected', function (params) {
  818. self.trigger('select', params);
  819. self.trigger('close');
  820. });
  821. this.results.on('unselected', function (params) {
  822. self.trigger('unselect', params);
  823. self.trigger('close');
  824. });
  825. this.on('open', function () {
  826. $container.addClass('open');
  827. });
  828. this.on('close', function () {
  829. $container.removeClass('open');
  830. });
  831. // Set the initial state
  832. this.data.current(function (initialData) {
  833. self.trigger('selection:update', {
  834. data: initialData
  835. });
  836. });
  837. this.on('query', function (params) {
  838. this.data.query(params, function (data) {
  839. self.trigger('results:all', {
  840. data: data,
  841. query: params
  842. });
  843. });
  844. });
  845. this.trigger('query', {});
  846. // Hide the original select
  847. $element.hide();
  848. };
  849. Utils.Extend(Select2, Utils.Observable);
  850. Select2.prototype.toggleDropdown = function () {
  851. if (this.$container.hasClass('open')) {
  852. this.trigger('close');
  853. } else {
  854. this.trigger('open');
  855. }
  856. };
  857. Select2.prototype.render = function () {
  858. var $container = $(
  859. '<span class="select2 select2-container select2-theme-default">' +
  860. '<span class="selection"></span>' +
  861. '<span class="dropdown-wrapper"></span>' +
  862. '</span>'
  863. );
  864. return $container;
  865. };
  866. return Select2;
  867. });
  868. define('jquery.select2',[
  869. 'jquery',
  870. 'select2/core'
  871. ], function ($, Select2) {
  872. if ($.fn.select2 == null) {
  873. $.fn.select2 = function (options) {
  874. options = options || {};
  875. if (typeof options === 'object') {
  876. this.each(function () {
  877. var instance = new Select2($(this), options);
  878. });
  879. } else if (typeof options === 'string') {
  880. var instance = this.data('select2');
  881. instance[options](arguments.slice(1));
  882. } else {
  883. throw new Error('Invalid arguments for Select2: ' + options);
  884. }
  885. };
  886. }
  887. return Select2;
  888. });