angular-dual-listbox.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. import { Component, IterableDiffers, Input, Output, EventEmitter, NgModule } from '@angular/core';
  2. import { CommonModule } from '@angular/common';
  3. import { FormsModule } from '@angular/forms';
  4. /**
  5. * @fileoverview added by tsickle
  6. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7. */
  8. var BasicList = /** @class */ (function () {
  9. function BasicList(name) {
  10. this._name = name;
  11. this.last = null;
  12. this.picker = '';
  13. this.dragStart = false;
  14. this.dragOver = false;
  15. // Arrays will contain objects of { _id, _name }.
  16. this.pick = [];
  17. this.list = [];
  18. this.sift = [];
  19. }
  20. Object.defineProperty(BasicList.prototype, "name", {
  21. get: /**
  22. * @return {?}
  23. */
  24. function () {
  25. return this._name;
  26. },
  27. enumerable: true,
  28. configurable: true
  29. });
  30. return BasicList;
  31. }());
  32. /**
  33. * @fileoverview added by tsickle
  34. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  35. */
  36. /** @type {?} */
  37. var nextId = 0;
  38. var DualListComponent = /** @class */ (function () {
  39. function DualListComponent(differs) {
  40. this.differs = differs;
  41. this.id = "dual-list-" + nextId++;
  42. this.key = '_id';
  43. this.display = '_name';
  44. this.height = '100px';
  45. this.filter = false;
  46. this.format = DualListComponent.DEFAULT_FORMAT;
  47. this.sort = false;
  48. this.disabled = false;
  49. this.destinationChange = new EventEmitter();
  50. this.sorter = (/**
  51. * @param {?} a
  52. * @param {?} b
  53. * @return {?}
  54. */
  55. function (a, b) { return (a._name < b._name) ? -1 : ((a._name > b._name) ? 1 : 0); });
  56. this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
  57. this.confirmed = new BasicList(DualListComponent.CONFIRMED_LIST_NAME);
  58. }
  59. /**
  60. * @param {?} changeRecord
  61. * @return {?}
  62. */
  63. DualListComponent.prototype.ngOnChanges = /**
  64. * @param {?} changeRecord
  65. * @return {?}
  66. */
  67. function (changeRecord) {
  68. if (changeRecord['filter']) {
  69. if (changeRecord['filter'].currentValue === false) {
  70. this.clearFilter(this.available);
  71. this.clearFilter(this.confirmed);
  72. }
  73. }
  74. if (changeRecord['sort']) {
  75. if (changeRecord['sort'].currentValue === true && this.compare === undefined) {
  76. this.compare = this.sorter;
  77. }
  78. else if (changeRecord['sort'].currentValue === false) {
  79. this.compare = undefined;
  80. }
  81. }
  82. if (changeRecord['format']) {
  83. this.format = changeRecord['format'].currentValue;
  84. if (typeof (this.format.direction) === 'undefined') {
  85. this.format.direction = DualListComponent.LTR;
  86. }
  87. if (typeof (this.format.add) === 'undefined') {
  88. this.format.add = DualListComponent.DEFAULT_FORMAT.add;
  89. }
  90. if (typeof (this.format.remove) === 'undefined') {
  91. this.format.remove = DualListComponent.DEFAULT_FORMAT.remove;
  92. }
  93. if (typeof (this.format.all) === 'undefined') {
  94. this.format.all = DualListComponent.DEFAULT_FORMAT.all;
  95. }
  96. if (typeof (this.format.none) === 'undefined') {
  97. this.format.none = DualListComponent.DEFAULT_FORMAT.none;
  98. }
  99. if (typeof (this.format.draggable) === 'undefined') {
  100. this.format.draggable = DualListComponent.DEFAULT_FORMAT.draggable;
  101. }
  102. }
  103. if (changeRecord['source']) {
  104. this.available = new BasicList(DualListComponent.AVAILABLE_LIST_NAME);
  105. this.updatedSource();
  106. this.updatedDestination();
  107. }
  108. if (changeRecord['destination']) {
  109. this.confirmed = new BasicList(DualListComponent.CONFIRMED_LIST_NAME);
  110. this.updatedDestination();
  111. this.updatedSource();
  112. }
  113. };
  114. /**
  115. * @return {?}
  116. */
  117. DualListComponent.prototype.ngDoCheck = /**
  118. * @return {?}
  119. */
  120. function () {
  121. if (this.source && this.buildAvailable(this.source)) {
  122. this.onFilter(this.available);
  123. }
  124. if (this.destination && this.buildConfirmed(this.destination)) {
  125. this.onFilter(this.confirmed);
  126. }
  127. };
  128. /**
  129. * @param {?} source
  130. * @return {?}
  131. */
  132. DualListComponent.prototype.buildAvailable = /**
  133. * @param {?} source
  134. * @return {?}
  135. */
  136. function (source) {
  137. var _this = this;
  138. /** @type {?} */
  139. var sourceChanges = this.sourceDiffer.diff(source);
  140. if (sourceChanges) {
  141. sourceChanges.forEachRemovedItem((/**
  142. * @param {?} r
  143. * @return {?}
  144. */
  145. function (r) {
  146. /** @type {?} */
  147. var idx = _this.findItemIndex(_this.available.list, r.item, _this.key);
  148. if (idx !== -1) {
  149. _this.available.list.splice(idx, 1);
  150. }
  151. }));
  152. sourceChanges.forEachAddedItem((/**
  153. * @param {?} r
  154. * @return {?}
  155. */
  156. function (r) {
  157. // Do not add duplicates even if source has duplicates.
  158. if (_this.findItemIndex(_this.available.list, r.item, _this.key) === -1) {
  159. _this.available.list.push({ _id: _this.makeId(r.item), _name: _this.makeName(r.item) });
  160. }
  161. }));
  162. if (this.compare !== undefined) {
  163. this.available.list.sort(this.compare);
  164. }
  165. this.available.sift = this.available.list;
  166. return true;
  167. }
  168. return false;
  169. };
  170. /**
  171. * @param {?} destination
  172. * @return {?}
  173. */
  174. DualListComponent.prototype.buildConfirmed = /**
  175. * @param {?} destination
  176. * @return {?}
  177. */
  178. function (destination) {
  179. var _this = this;
  180. /** @type {?} */
  181. var moved = false;
  182. /** @type {?} */
  183. var destChanges = this.destinationDiffer.diff(destination);
  184. if (destChanges) {
  185. destChanges.forEachRemovedItem((/**
  186. * @param {?} r
  187. * @return {?}
  188. */
  189. function (r) {
  190. /** @type {?} */
  191. var idx = _this.findItemIndex(_this.confirmed.list, r.item, _this.key);
  192. if (idx !== -1) {
  193. if (!_this.isItemSelected(_this.confirmed.pick, _this.confirmed.list[idx])) {
  194. _this.selectItem(_this.confirmed.pick, _this.confirmed.list[idx]);
  195. }
  196. _this.moveItem(_this.confirmed, _this.available, _this.confirmed.list[idx], false);
  197. moved = true;
  198. }
  199. }));
  200. destChanges.forEachAddedItem((/**
  201. * @param {?} r
  202. * @return {?}
  203. */
  204. function (r) {
  205. /** @type {?} */
  206. var idx = _this.findItemIndex(_this.available.list, r.item, _this.key);
  207. if (idx !== -1) {
  208. if (!_this.isItemSelected(_this.available.pick, _this.available.list[idx])) {
  209. _this.selectItem(_this.available.pick, _this.available.list[idx]);
  210. }
  211. _this.moveItem(_this.available, _this.confirmed, _this.available.list[idx], false);
  212. moved = true;
  213. }
  214. }));
  215. if (this.compare !== undefined) {
  216. this.confirmed.list.sort(this.compare);
  217. }
  218. this.confirmed.sift = this.confirmed.list;
  219. if (moved) {
  220. this.trueUp();
  221. }
  222. return true;
  223. }
  224. return false;
  225. };
  226. /**
  227. * @return {?}
  228. */
  229. DualListComponent.prototype.updatedSource = /**
  230. * @return {?}
  231. */
  232. function () {
  233. this.available.list.length = 0;
  234. this.available.pick.length = 0;
  235. if (this.source !== undefined) {
  236. this.sourceDiffer = this.differs.find(this.source).create(null);
  237. }
  238. };
  239. /**
  240. * @return {?}
  241. */
  242. DualListComponent.prototype.updatedDestination = /**
  243. * @return {?}
  244. */
  245. function () {
  246. if (this.destination !== undefined) {
  247. this.destinationDiffer = this.differs.find(this.destination).create(null);
  248. }
  249. };
  250. /**
  251. * @return {?}
  252. */
  253. DualListComponent.prototype.direction = /**
  254. * @return {?}
  255. */
  256. function () {
  257. return this.format.direction === DualListComponent.LTR;
  258. };
  259. /**
  260. * @param {?=} list
  261. * @return {?}
  262. */
  263. DualListComponent.prototype.dragEnd = /**
  264. * @param {?=} list
  265. * @return {?}
  266. */
  267. function (list) {
  268. if (list === void 0) { list = null; }
  269. if (list) {
  270. list.dragStart = false;
  271. }
  272. else {
  273. this.available.dragStart = false;
  274. this.confirmed.dragStart = false;
  275. }
  276. return false;
  277. };
  278. /**
  279. * @param {?} event
  280. * @param {?} item
  281. * @param {?} list
  282. * @return {?}
  283. */
  284. DualListComponent.prototype.drag = /**
  285. * @param {?} event
  286. * @param {?} item
  287. * @param {?} list
  288. * @return {?}
  289. */
  290. function (event, item, list) {
  291. if (!this.isItemSelected(list.pick, item)) {
  292. this.selectItem(list.pick, item);
  293. }
  294. list.dragStart = true;
  295. // Set a custom type to be this dual-list's id.
  296. event.dataTransfer.setData(this.id, item['_id']);
  297. };
  298. /**
  299. * @param {?} event
  300. * @param {?} list
  301. * @return {?}
  302. */
  303. DualListComponent.prototype.allowDrop = /**
  304. * @param {?} event
  305. * @param {?} list
  306. * @return {?}
  307. */
  308. function (event, list) {
  309. if (event.dataTransfer.types.length && (event.dataTransfer.types[0] === this.id)) {
  310. event.preventDefault();
  311. if (!list.dragStart) {
  312. list.dragOver = true;
  313. }
  314. }
  315. return false;
  316. };
  317. /**
  318. * @return {?}
  319. */
  320. DualListComponent.prototype.dragLeave = /**
  321. * @return {?}
  322. */
  323. function () {
  324. this.available.dragOver = false;
  325. this.confirmed.dragOver = false;
  326. };
  327. /**
  328. * @param {?} event
  329. * @param {?} list
  330. * @return {?}
  331. */
  332. DualListComponent.prototype.drop = /**
  333. * @param {?} event
  334. * @param {?} list
  335. * @return {?}
  336. */
  337. function (event, list) {
  338. if (event.dataTransfer.types.length && (event.dataTransfer.types[0] === this.id)) {
  339. event.preventDefault();
  340. this.dragLeave();
  341. this.dragEnd();
  342. if (list === this.available) {
  343. this.moveItem(this.available, this.confirmed);
  344. }
  345. else {
  346. this.moveItem(this.confirmed, this.available);
  347. }
  348. }
  349. };
  350. /**
  351. * @private
  352. * @return {?}
  353. */
  354. DualListComponent.prototype.trueUp = /**
  355. * @private
  356. * @return {?}
  357. */
  358. function () {
  359. var _this = this;
  360. /** @type {?} */
  361. var changed = false;
  362. // Clear removed items.
  363. /** @type {?} */
  364. var pos = this.destination.length;
  365. while ((pos -= 1) >= 0) {
  366. /** @type {?} */
  367. var mv = this.confirmed.list.filter((/**
  368. * @param {?} conf
  369. * @return {?}
  370. */
  371. function (conf) {
  372. if (typeof _this.destination[pos] === 'object') {
  373. return conf._id === _this.destination[pos][_this.key];
  374. }
  375. else {
  376. return conf._id === _this.destination[pos];
  377. }
  378. }));
  379. if (mv.length === 0) {
  380. // Not found so remove.
  381. this.destination.splice(pos, 1);
  382. changed = true;
  383. }
  384. }
  385. var _loop_1 = function (i, len) {
  386. /** @type {?} */
  387. var mv = this_1.destination.filter((/**
  388. * @param {?} d
  389. * @return {?}
  390. */
  391. function (d) {
  392. if (typeof d === 'object') {
  393. return (d[_this.key] === _this.confirmed.list[i]._id);
  394. }
  395. else {
  396. return (d === _this.confirmed.list[i]._id);
  397. }
  398. }));
  399. if (mv.length === 0) {
  400. // Not found so add.
  401. mv = this_1.source.filter((/**
  402. * @param {?} o
  403. * @return {?}
  404. */
  405. function (o) {
  406. if (typeof o === 'object') {
  407. return (o[_this.key] === _this.confirmed.list[i]._id);
  408. }
  409. else {
  410. return (o === _this.confirmed.list[i]._id);
  411. }
  412. }));
  413. if (mv.length > 0) {
  414. this_1.destination.push(mv[0]);
  415. changed = true;
  416. }
  417. }
  418. };
  419. var this_1 = this;
  420. // Push added items.
  421. for (var i = 0, len = this.confirmed.list.length; i < len; i += 1) {
  422. _loop_1(i);
  423. }
  424. if (changed) {
  425. this.destinationChange.emit(this.destination);
  426. }
  427. };
  428. /**
  429. * @param {?} list
  430. * @param {?} item
  431. * @param {?=} key
  432. * @return {?}
  433. */
  434. DualListComponent.prototype.findItemIndex = /**
  435. * @param {?} list
  436. * @param {?} item
  437. * @param {?=} key
  438. * @return {?}
  439. */
  440. function (list, item, key) {
  441. if (key === void 0) { key = '_id'; }
  442. /** @type {?} */
  443. var idx = -1;
  444. /**
  445. * @param {?} e
  446. * @return {?}
  447. */
  448. function matchObject(e) {
  449. if (e._id === item[key]) {
  450. idx = list.indexOf(e);
  451. return true;
  452. }
  453. return false;
  454. }
  455. /**
  456. * @param {?} e
  457. * @return {?}
  458. */
  459. function match(e) {
  460. if (e._id === item) {
  461. idx = list.indexOf(e);
  462. return true;
  463. }
  464. return false;
  465. }
  466. // Assumption is that the arrays do not have duplicates.
  467. if (typeof item === 'object') {
  468. list.filter(matchObject);
  469. }
  470. else {
  471. list.filter(match);
  472. }
  473. return idx;
  474. };
  475. /**
  476. * @private
  477. * @param {?} source
  478. * @param {?} item
  479. * @return {?}
  480. */
  481. DualListComponent.prototype.makeUnavailable = /**
  482. * @private
  483. * @param {?} source
  484. * @param {?} item
  485. * @return {?}
  486. */
  487. function (source, item) {
  488. /** @type {?} */
  489. var idx = source.list.indexOf(item);
  490. if (idx !== -1) {
  491. source.list.splice(idx, 1);
  492. }
  493. };
  494. /**
  495. * @param {?} source
  496. * @param {?} target
  497. * @param {?=} item
  498. * @param {?=} trueup
  499. * @return {?}
  500. */
  501. DualListComponent.prototype.moveItem = /**
  502. * @param {?} source
  503. * @param {?} target
  504. * @param {?=} item
  505. * @param {?=} trueup
  506. * @return {?}
  507. */
  508. function (source, target, item, trueup) {
  509. var _this = this;
  510. if (item === void 0) { item = null; }
  511. if (trueup === void 0) { trueup = true; }
  512. /** @type {?} */
  513. var i = 0;
  514. /** @type {?} */
  515. var len = source.pick.length;
  516. if (item) {
  517. i = source.list.indexOf(item);
  518. len = i + 1;
  519. }
  520. var _loop_2 = function () {
  521. // Is the pick still in list?
  522. /** @type {?} */
  523. var mv = [];
  524. if (item) {
  525. /** @type {?} */
  526. var idx = this_2.findItemIndex(source.pick, item);
  527. if (idx !== -1) {
  528. mv[0] = source.pick[idx];
  529. }
  530. }
  531. else {
  532. mv = source.list.filter((/**
  533. * @param {?} src
  534. * @return {?}
  535. */
  536. function (src) {
  537. return (src._id === source.pick[i]._id);
  538. }));
  539. }
  540. // Should only ever be 1
  541. if (mv.length === 1) {
  542. // Add if not already in target.
  543. if (target.list.filter((/**
  544. * @param {?} trg
  545. * @return {?}
  546. */
  547. function (trg) { return trg._id === mv[0]._id; })).length === 0) {
  548. target.list.push(mv[0]);
  549. }
  550. this_2.makeUnavailable(source, mv[0]);
  551. }
  552. };
  553. var this_2 = this;
  554. for (; i < len; i += 1) {
  555. _loop_2();
  556. }
  557. if (this.compare !== undefined) {
  558. target.list.sort(this.compare);
  559. }
  560. source.pick.length = 0;
  561. // Update destination
  562. if (trueup) {
  563. this.trueUp();
  564. }
  565. // Delay ever-so-slightly to prevent race condition.
  566. setTimeout((/**
  567. * @return {?}
  568. */
  569. function () {
  570. _this.onFilter(source);
  571. _this.onFilter(target);
  572. }), 10);
  573. };
  574. /**
  575. * @param {?} list
  576. * @param {?} item
  577. * @return {?}
  578. */
  579. DualListComponent.prototype.isItemSelected = /**
  580. * @param {?} list
  581. * @param {?} item
  582. * @return {?}
  583. */
  584. function (list, item) {
  585. if (list.filter((/**
  586. * @param {?} e
  587. * @return {?}
  588. */
  589. function (e) { return Object.is(e, item); })).length > 0) {
  590. return true;
  591. }
  592. return false;
  593. };
  594. /**
  595. * @param {?} event
  596. * @param {?} index
  597. * @param {?} source
  598. * @param {?} item
  599. * @return {?}
  600. */
  601. DualListComponent.prototype.shiftClick = /**
  602. * @param {?} event
  603. * @param {?} index
  604. * @param {?} source
  605. * @param {?} item
  606. * @return {?}
  607. */
  608. function (event, index, source, item) {
  609. if (event.shiftKey && source.last && !Object.is(item, source.last)) {
  610. /** @type {?} */
  611. var idx = source.sift.indexOf(source.last);
  612. if (index > idx) {
  613. for (var i = (idx + 1); i < index; i += 1) {
  614. this.selectItem(source.pick, source.sift[i]);
  615. }
  616. }
  617. else if (idx !== -1) {
  618. for (var i = (index + 1); i < idx; i += 1) {
  619. this.selectItem(source.pick, source.sift[i]);
  620. }
  621. }
  622. }
  623. source.last = item;
  624. };
  625. /**
  626. * @param {?} list
  627. * @param {?} item
  628. * @return {?}
  629. */
  630. DualListComponent.prototype.selectItem = /**
  631. * @param {?} list
  632. * @param {?} item
  633. * @return {?}
  634. */
  635. function (list, item) {
  636. /** @type {?} */
  637. var pk = list.filter((/**
  638. * @param {?} e
  639. * @return {?}
  640. */
  641. function (e) {
  642. return Object.is(e, item);
  643. }));
  644. if (pk.length > 0) {
  645. // Already in list, so deselect.
  646. for (var i = 0, len = pk.length; i < len; i += 1) {
  647. /** @type {?} */
  648. var idx = list.indexOf(pk[i]);
  649. if (idx !== -1) {
  650. list.splice(idx, 1);
  651. }
  652. }
  653. }
  654. else {
  655. list.push(item);
  656. }
  657. };
  658. /**
  659. * @param {?} source
  660. * @return {?}
  661. */
  662. DualListComponent.prototype.selectAll = /**
  663. * @param {?} source
  664. * @return {?}
  665. */
  666. function (source) {
  667. source.pick.length = 0;
  668. source.pick = source.sift.slice(0);
  669. };
  670. /**
  671. * @param {?} source
  672. * @return {?}
  673. */
  674. DualListComponent.prototype.selectNone = /**
  675. * @param {?} source
  676. * @return {?}
  677. */
  678. function (source) {
  679. source.pick.length = 0;
  680. };
  681. /**
  682. * @param {?} source
  683. * @return {?}
  684. */
  685. DualListComponent.prototype.isAllSelected = /**
  686. * @param {?} source
  687. * @return {?}
  688. */
  689. function (source) {
  690. if (source.list.length === 0 || source.list.length === source.pick.length) {
  691. return true;
  692. }
  693. return false;
  694. };
  695. /**
  696. * @param {?} source
  697. * @return {?}
  698. */
  699. DualListComponent.prototype.isAnySelected = /**
  700. * @param {?} source
  701. * @return {?}
  702. */
  703. function (source) {
  704. if (source.pick.length > 0) {
  705. return true;
  706. }
  707. return false;
  708. };
  709. /**
  710. * @private
  711. * @param {?} source
  712. * @return {?}
  713. */
  714. DualListComponent.prototype.unpick = /**
  715. * @private
  716. * @param {?} source
  717. * @return {?}
  718. */
  719. function (source) {
  720. for (var i = source.pick.length - 1; i >= 0; i -= 1) {
  721. if (source.sift.indexOf(source.pick[i]) === -1) {
  722. source.pick.splice(i, 1);
  723. }
  724. }
  725. };
  726. /**
  727. * @param {?} source
  728. * @return {?}
  729. */
  730. DualListComponent.prototype.clearFilter = /**
  731. * @param {?} source
  732. * @return {?}
  733. */
  734. function (source) {
  735. if (source) {
  736. source.picker = '';
  737. this.onFilter(source);
  738. }
  739. };
  740. /**
  741. * @param {?} source
  742. * @return {?}
  743. */
  744. DualListComponent.prototype.onFilter = /**
  745. * @param {?} source
  746. * @return {?}
  747. */
  748. function (source) {
  749. var _this = this;
  750. if (source.picker.length > 0) {
  751. try {
  752. /** @type {?} */
  753. var filtered = source.list.filter((/**
  754. * @param {?} item
  755. * @return {?}
  756. */
  757. function (item) {
  758. if (Object.prototype.toString.call(item) === '[object Object]') {
  759. if (item._name !== undefined) {
  760. // @ts-ignore: remove when d.ts has locale as an argument.
  761. return item._name.toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  762. }
  763. else {
  764. // @ts-ignore: remove when d.ts has locale as an argument.
  765. return JSON.stringify(item).toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  766. }
  767. }
  768. else {
  769. // @ts-ignore: remove when d.ts has locale as an argument.
  770. return item.toLocaleLowerCase(_this.format.locale).indexOf(source.picker.toLocaleLowerCase(_this.format.locale)) !== -1;
  771. }
  772. }));
  773. source.sift = filtered;
  774. this.unpick(source);
  775. }
  776. catch (e) {
  777. if (e instanceof RangeError) {
  778. this.format.locale = undefined;
  779. }
  780. source.sift = source.list;
  781. }
  782. }
  783. else {
  784. source.sift = source.list;
  785. }
  786. };
  787. /**
  788. * @private
  789. * @param {?} item
  790. * @return {?}
  791. */
  792. DualListComponent.prototype.makeId = /**
  793. * @private
  794. * @param {?} item
  795. * @return {?}
  796. */
  797. function (item) {
  798. if (typeof item === 'object') {
  799. return item[this.key];
  800. }
  801. else {
  802. return item;
  803. }
  804. };
  805. // Allow for complex names by passing an array of strings.
  806. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  807. // Allow for complex names by passing an array of strings.
  808. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  809. /**
  810. * @protected
  811. * @param {?} item
  812. * @param {?=} separator
  813. * @return {?}
  814. */
  815. DualListComponent.prototype.makeName =
  816. // Allow for complex names by passing an array of strings.
  817. // Example: [display]="[ '_type.substring(0,1)', '_name' ]"
  818. /**
  819. * @protected
  820. * @param {?} item
  821. * @param {?=} separator
  822. * @return {?}
  823. */
  824. function (item, separator) {
  825. if (separator === void 0) { separator = '_'; }
  826. /** @type {?} */
  827. var display = this.display;
  828. /**
  829. * @param {?} itm
  830. * @return {?}
  831. */
  832. function fallback(itm) {
  833. switch (Object.prototype.toString.call(itm)) {
  834. case '[object Number]':
  835. return itm;
  836. case '[object String]':
  837. return itm;
  838. default:
  839. if (itm !== undefined) {
  840. return itm[display];
  841. }
  842. else {
  843. return 'undefined';
  844. }
  845. }
  846. }
  847. /** @type {?} */
  848. var str = '';
  849. if (this.display !== undefined) {
  850. switch (Object.prototype.toString.call(this.display)) {
  851. case '[object Function]':
  852. str = this.display(item);
  853. break;
  854. case '[object Array]':
  855. for (var i = 0, len = this.display.length; i < len; i += 1) {
  856. if (str.length > 0) {
  857. str = str + separator;
  858. }
  859. if (this.display[i].indexOf('.') === -1) {
  860. // Simple, just add to string.
  861. str = str + item[this.display[i]];
  862. }
  863. else {
  864. // Complex, some action needs to be performed
  865. /** @type {?} */
  866. var parts = this.display[i].split('.');
  867. /** @type {?} */
  868. var s = item[parts[0]];
  869. if (s) {
  870. // Use brute force
  871. if (parts[1].indexOf('substring') !== -1) {
  872. /** @type {?} */
  873. var nums = (parts[1].substring(parts[1].indexOf('(') + 1, parts[1].indexOf(')'))).split(',');
  874. switch (nums.length) {
  875. case 1:
  876. str = str + s.substring(parseInt(nums[0], 10));
  877. break;
  878. case 2:
  879. str = str + s.substring(parseInt(nums[0], 10), parseInt(nums[1], 10));
  880. break;
  881. default:
  882. str = str + s;
  883. break;
  884. }
  885. }
  886. else {
  887. // method not approved, so just add s.
  888. str = str + s;
  889. }
  890. }
  891. }
  892. }
  893. break;
  894. default:
  895. str = fallback(item);
  896. break;
  897. }
  898. }
  899. else {
  900. str = fallback(item);
  901. }
  902. return str;
  903. };
  904. DualListComponent.AVAILABLE_LIST_NAME = 'available';
  905. DualListComponent.CONFIRMED_LIST_NAME = 'confirmed';
  906. DualListComponent.LTR = 'left-to-right';
  907. DualListComponent.RTL = 'right-to-left';
  908. DualListComponent.DEFAULT_FORMAT = {
  909. add: 'Add',
  910. remove: 'Remove',
  911. all: 'All',
  912. none: 'None',
  913. direction: DualListComponent.LTR,
  914. draggable: true,
  915. locale: undefined
  916. };
  917. DualListComponent.decorators = [
  918. { type: Component, args: [{
  919. selector: 'dual-list',
  920. template: "<div class=\"dual-list\">\n\t<div class=\"listbox\" [ngStyle]=\"{ 'order' : direction() ? 1 : 2, 'margin-left' : direction() ? 0 : '10px' }\">\n\t\t<button type=\"button\" name=\"addBtn\" class=\"btn btn-primary btn-block\"\n\t\t\t(click)=\"moveItem(available, confirmed)\" [ngClass]=\"direction() ? 'point-right' : 'point-left'\"\n\t\t\t[disabled]=\"available.pick.length === 0\">{{format.add}}</button>\n\n\t\t<form *ngIf=\"filter\" class=\"filter\">\n\t\t\t<input class=\"form-control\" name=\"filterSource\" [(ngModel)]=\"available.picker\" (ngModelChange)=\"onFilter(available)\">\n\t\t</form>\n\n\t\t<div class=\"record-picker\">\n\t\t\t<ul [ngStyle]=\"{'max-height': height, 'min-height': height}\" [ngClass]=\"{over:available.dragOver}\"\n\t\t\t\t(drop)=\"drop($event, confirmed)\" (dragover)=\"allowDrop($event, available)\" (dragleave)=\"dragLeave()\">\n\t\t\t\t<li *ngFor=\"let item of available.sift; let idx=index;\"\n\t\t\t\t\t(click)=\"disabled ? null : selectItem(available.pick, item); shiftClick($event, idx, available, item)\"\n\t\t\t\t\t[ngClass]=\"{selected: isItemSelected(available.pick, item), disabled: disabled}\"\n\t\t\t\t\t[draggable]=\"!disabled && format.draggable\" (dragstart)=\"drag($event, item, available)\" (dragend)=\"dragEnd(available)\"\n\t\t\t\t><label>{{item._name}}</label></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"button-bar\">\n\t\t\t<button type=\"button\" class=\"btn btn-primary pull-left\" (click)=\"selectAll(available)\"\n\t\t\t\t[disabled]=\"disabled || isAllSelected(available)\">{{format.all}}</button>\n\t\t\t<button type=\"button\" class=\"btn btn-default pull-right\" (click)=\"selectNone(available)\"\n\t\t\t\t[disabled]=\"!isAnySelected(available)\">{{format.none}}</button>\n\t\t</div>\n\t</div>\n\n\t<div class=\"listbox\" [ngStyle]=\"{ 'order' : direction() ? 2 : 1, 'margin-left' : direction() ? '10px' : 0 }\">\n\t\t<button type=\"button\" name=\"removeBtn\" class=\"btn btn-primary btn-block\"\n\t\t\t(click)=\"moveItem(confirmed, available)\" [ngClass]=\"direction() ? 'point-left' : 'point-right'\"\n\t\t\t[disabled]=\"confirmed.pick.length === 0\">{{format.remove}}</button>\n\n\t\t<form *ngIf=\"filter\" class=\"filter\">\n\t\t\t<input class=\"form-control\" name=\"filterDestination\" [(ngModel)]=\"confirmed.picker\" (ngModelChange)=\"onFilter(confirmed)\">\n\t\t</form>\n\n\t\t<div class=\"record-picker\">\n\t\t\t<ul [ngStyle]=\"{'max-height': height, 'min-height': height}\" [ngClass]=\"{over:confirmed.dragOver}\"\n\t\t\t\t(drop)=\"drop($event, available)\" (dragover)=\"allowDrop($event, confirmed)\" (dragleave)=\"dragLeave()\">\n\t\t\t\t<li #itmConf *ngFor=\"let item of confirmed.sift; let idx=index;\"\n\t\t\t\t\t(click)=\"disabled ? null : selectItem(confirmed.pick, item); shiftClick($event, idx, confirmed, item)\"\n\t\t\t\t\t[ngClass]=\"{selected: isItemSelected(confirmed.pick, item), disabled: disabled}\"\n\t\t\t\t\t[draggable]=\"!disabled && format.draggable\" (dragstart)=\"drag($event, item, confirmed)\" (dragend)=\"dragEnd(confirmed)\"\n\t\t\t\t><label>{{item._name}}</label></li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"button-bar\">\n\t\t\t<button type=\"button\" class=\"btn btn-primary pull-left\" (click)=\"selectAll(confirmed)\"\n\t\t\t\t[disabled]=\"disabled || isAllSelected(confirmed)\">{{format.all}}</button>\n\t\t\t<button type=\"button\" class=\"btn btn-default pull-right\" (click)=\"selectNone(confirmed)\"\n\t\t\t\t[disabled]=\"!isAnySelected(confirmed)\">{{format.none}}</button>\n\t\t</div>\n\t</div>\n</div>\n",
  921. styles: ["div.record-picker{overflow-x:hidden;overflow-y:auto;border:1px solid #ddd;border-radius:8px;position:relative;cursor:pointer;scrollbar-base-color:#337ab7;scrollbar-3dlight-color:#337ab7;scrollbar-highlight-color:#337ab7;scrollbar-track-color:#eee;scrollbar-arrow-color:gray;scrollbar-shadow-color:gray;scrollbar-dark-shadow-color:gray}div.record-picker::-webkit-scrollbar{width:12px}div.record-picker::-webkit-scrollbar-button{width:0;height:0}div.record-picker::-webkit-scrollbar-track{background:#eee;box-shadow:0 0 3px #dfdfdf inset;border-top-right-radius:8px;border-bottom-right-radius:8px}div.record-picker::-webkit-scrollbar-thumb{background:#337ab7;border:thin solid gray;border-top-right-radius:8px;border-bottom-right-radius:8px}div.record-picker::-webkit-scrollbar-thumb:hover{background:#286090}.record-picker ul{margin:0;padding:0 0 1px}.record-picker li{border-top:thin solid #ddd;border-bottom:1px solid #ddd;display:block;padding:2px 2px 2px 10px;margin-bottom:-1px;font-size:.85em;cursor:pointer;white-space:nowrap;min-height:16px}.record-picker li:hover{background-color:#f5f5f5}.record-picker li.selected{background-color:#d9edf7}.record-picker li.selected:hover{background-color:#c4e3f3}.record-picker li.disabled{opacity:.5;cursor:default;background-color:inherit}.record-picker li:first-child{border-top-left-radius:8px;border-top-right-radius:8px;border-top:none}.record-picker li:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-bottom:none}.record-picker label{cursor:pointer;font-weight:inherit;font-size:14px;padding:4px;margin-bottom:-1px;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.record-picker ul.over{background-color:#d3d3d3}.dual-list{display:flex;flex-direction:row;align-content:flex-start}.dual-list .listbox{width:50%;margin:0}.dual-list .button-bar{margin-top:8px}.point-right::after{content:\"\\25B6\";padding-left:1em}.point-left::before{content:\"\\25C0\";padding-right:1em}.dual-list .button-bar button{width:47%}button.btn-block{display:block;width:100%;margin-bottom:8px}.filter{margin-bottom:-2.2em}.filter::after{content:\"o\";width:40px;color:transparent;font-size:2em;background-image:url('data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M0 64l192 192v192l128-32V256L512 64H0z\"/></svg>');background-repeat:no-repeat;background-position:center center;opacity:.2;top:-36px;left:calc(100% - 21px);position:relative}"]
  922. }] }
  923. ];
  924. /** @nocollapse */
  925. DualListComponent.ctorParameters = function () { return [
  926. { type: IterableDiffers }
  927. ]; };
  928. DualListComponent.propDecorators = {
  929. id: [{ type: Input }],
  930. key: [{ type: Input }],
  931. display: [{ type: Input }],
  932. height: [{ type: Input }],
  933. filter: [{ type: Input }],
  934. format: [{ type: Input }],
  935. sort: [{ type: Input }],
  936. compare: [{ type: Input }],
  937. disabled: [{ type: Input }],
  938. source: [{ type: Input }],
  939. destination: [{ type: Input }],
  940. destinationChange: [{ type: Output }]
  941. };
  942. return DualListComponent;
  943. }());
  944. /**
  945. * @fileoverview added by tsickle
  946. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  947. */
  948. var AngularDualListBoxModule = /** @class */ (function () {
  949. function AngularDualListBoxModule() {
  950. }
  951. AngularDualListBoxModule.decorators = [
  952. { type: NgModule, args: [{
  953. imports: [
  954. CommonModule,
  955. FormsModule
  956. ],
  957. declarations: [DualListComponent],
  958. exports: [DualListComponent]
  959. },] }
  960. ];
  961. return AngularDualListBoxModule;
  962. }());
  963. /**
  964. * @fileoverview added by tsickle
  965. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  966. */
  967. /**
  968. * @fileoverview added by tsickle
  969. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  970. */
  971. export { AngularDualListBoxModule, BasicList, DualListComponent };
  972. //# sourceMappingURL=angular-dual-listbox.js.map