region-selection.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /// <reference path="../../node_modules/@types/jquery/index.d.ts"/>
  2. namespace RegionSelection {
  3. function foreach(data, callback: (value: any, key?: number | string, array?: Array<any>) => void) {
  4. for (let key in data) {
  5. if (data.hasOwnProperty(key) && typeof data[key] !== 'function') {
  6. callback(data[key], key, data);
  7. }
  8. }
  9. }
  10. class RegionsCollection {
  11. [index: number]: Region;
  12. public constructor(data: Region[]) {
  13. let length = 0;
  14. this.setLength = function (value: number) {
  15. length = value;
  16. };
  17. this.getLength = function () {
  18. return length;
  19. };
  20. foreach(data, (region: Region) => this.push(region));
  21. }
  22. get length() {
  23. return this.getLength();
  24. };
  25. set length(value: number) {
  26. this.setLength(value);
  27. }
  28. public setLength(value: number) {
  29. };
  30. public getLength(): number {
  31. return 0;
  32. };
  33. public push(item: Region) {
  34. Array.prototype.push.call(this, item);
  35. }
  36. public forEach(callback: (value: any, key?: number | string, array?: Array<any>) => void) {
  37. Array.prototype.forEach.call(this, callback);
  38. }
  39. public group(groupFunction: (region: Region) => string): { [groupName: string]: RegionsCollection } {
  40. let groups = {};
  41. this.forEach((region: Region) => {
  42. let groupName = groupFunction(region);
  43. if (groups[groupName] === undefined) {
  44. groups[groupName] = new RegionsCollection([]);
  45. }
  46. groups[groupName].push(region);
  47. });
  48. return groups;
  49. }
  50. public sort(sortFunction: (region1: Region, region2: Region) => number): RegionsCollection {
  51. let data = [];
  52. this.forEach((region) => data.push(region));
  53. data.sort(sortFunction);
  54. return new RegionsCollection(data);
  55. }
  56. }
  57. class RegionSelectionBox {
  58. private selector: JQuery;
  59. private regions: RegionsCollection = new RegionsCollection([]);
  60. private box: JQuery;
  61. constructor(selector: JQuery) {
  62. this.selector = selector;
  63. if (this.selector.data('regions') !== undefined) {
  64. this.fillRegions(this.selector.data('regions'));
  65. }
  66. this.selector.on('click', this.showBox.bind(this));
  67. }
  68. private fillRegions(data) {
  69. foreach(eval(data), (value: RegionInterface) => {
  70. this.regions.push(new Region(value));
  71. });
  72. }
  73. private showBox(e: JQueryEventObject) {
  74. e.preventDefault();
  75. e.stopPropagation();
  76. if (this.box === undefined) {
  77. this.renderBox();
  78. }
  79. let box = this.box;
  80. let hide = function () {
  81. box.hide(0, () => {
  82. $('body').off('click', hide);
  83. });
  84. }.bind(this);
  85. if (box.is(':visible')) {
  86. hide();
  87. } else {
  88. $('body').on('click', hide);
  89. box.show(0);
  90. }
  91. }
  92. private renderBox() {
  93. if (!$('.region__selection-box').length) {
  94. this.box = $('<div class="region__selection-box region-selection__box"></div>');
  95. let linkTemplate = '<a href="{link}" class="region-selection__link">{name}</a>';
  96. // let iconTemplate = '<img src="{icon}" class="region-selection__icon">';
  97. let grouped = this.regions.sort(function (region1: Region, region2: Region) {
  98. return region1.caption < region2.caption ? -1 : region1.caption > region2.caption ? 1 : 0;
  99. }).group((region: Region) => {
  100. return region.caption.charAt(0).toUpperCase();
  101. });
  102. foreach(grouped, (regionCollection: RegionsCollection, groupName) => {
  103. let itemsList = $('<div class="region-selection__items-list"></div>');
  104. itemsList.append($(`<div class="region-selection__list-letter">${groupName}</div>`));
  105. foreach(regionCollection, (region: Region) => {
  106. let item = $('<div class="region-selection__item"></div>').append(linkTemplate
  107. .replace('{link}', region.link)
  108. .replace('{name}', region.caption)
  109. // .replace('{icon}', iconTemplate.replace('{icon}', region.icon))
  110. );
  111. itemsList.append($(item));
  112. });
  113. this.box.append(itemsList);
  114. });
  115. this.box.css('display', 'none');
  116. this.selector.parent().append(this.box);
  117. }
  118. }
  119. }
  120. interface RegionInterface {
  121. id: number;
  122. caption: string;
  123. link: string;
  124. icon: string;
  125. }
  126. class Region {
  127. constructor(data: RegionInterface) {
  128. this._id = data.id;
  129. this._caption = data.caption;
  130. this._link = data.link;
  131. this._icon = data.icon;
  132. }
  133. private _id: number;
  134. get id() {
  135. return this._id;
  136. }
  137. private _caption: string;
  138. get caption() {
  139. return this._caption;
  140. }
  141. private _link: string;
  142. get link(): string {
  143. return this._link;
  144. }
  145. private _icon: string;
  146. get icon(): string {
  147. return this._icon;
  148. }
  149. }
  150. export function createSelectionBox($object: JQuery) {
  151. return new RegionSelectionBox($object);
  152. }
  153. }