fancycheckboxes.ts 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /// <reference path="../../node_modules/@types/jquery/index.d.ts"/>
  2. /// <reference path="../../node_modules/@types/fancybox/index.d.ts"/>
  3. namespace FancyCheckboxes {
  4. export class FancyCheckbox {
  5. public events: { [name: string]: { (responseText: string): void } [] } = {
  6. 'error': [],
  7. 'success': []
  8. };
  9. private $selector: JQuery;
  10. private checkboxData: any[];
  11. private selected: {} = {};
  12. public constructor($selector: JQuery) {
  13. this.$selector = $selector;
  14. this.checkboxData = [];
  15. this.populateCheckboxData(JSON.parse($selector.data('items') ? $selector.data('items').replace(/'/g, '"') : "[]"));
  16. this.$selector.click(this.onSelectorClick.bind(this));
  17. this.$selector.prev().append('<div class="selected-items"></div>');
  18. this.loadSelected();
  19. }
  20. private loadSelected() {
  21. let context = this;
  22. let first = true;
  23. let $selected = context.$selector.prev().find('.selected-items');
  24. this.selected = {};
  25. $selected.html('');
  26. console.dir($(this.$selector.data('field')).find(':selected'));
  27. $(this.$selector.data('field')).find(':selected').each(function () {
  28. context.selected[$(this).attr('value')] = $(this).html();
  29. if (!first) {
  30. $selected.append(', ')
  31. }
  32. if (first) {
  33. first = false;
  34. }
  35. $selected.append('<span>' + $(this).html() + '</span>');
  36. });
  37. console.dir(this.selected);
  38. }
  39. private onSelectorClick(event) {
  40. let context = this;
  41. let content = $('<div></div>');
  42. content.append('<div class="modal-header"><h3>' + this.$selector.html() + '</h3></div>');
  43. content.append('<div class="fancycheckboxes-items-container container">' + this.render().html() + '</div>');
  44. content.append('<div class="modal-footer"></div>');
  45. content.find('.modal-footer').append('<button type="submit" class="btn btn-primary">Выбрать</button>');
  46. let options = <FancyboxOptions> {
  47. content: '<div class="fancycheckboxes">' + content.html() + '</div>',
  48. type: 'html',
  49. modal: true,
  50. height: window.innerHeight,
  51. width: $('.mainBlock').outerWidth(),
  52. autoSize: false,
  53. afterClose: function () {
  54. context.loadSelected();
  55. },
  56. afterShow: function () {
  57. context.bindEvents();
  58. }
  59. };
  60. $.fancybox(options);
  61. }
  62. private bindEvents() {
  63. let context = this;
  64. let $fancy = $('.fancycheckboxes');
  65. $fancy.find('.more').each(function () {
  66. let $link = $(this);
  67. $link.on('click', function () {
  68. $link.parent().animate({height: $link.parent()[0].scrollHeight}, 200, function () {
  69. $link.parent().height('auto');
  70. $link.remove();
  71. });
  72. });
  73. });
  74. $fancy.find('.btn-primary').click(function () {
  75. $(context.$selector.data('field')).find('option').removeAttr('selected');
  76. $fancy.find('input:checked').each(function () {
  77. console.dir($(context.$selector.data('field'))
  78. .find('[value=' + $(this).attr('value') + ']'));
  79. $(context.$selector.data('field'))
  80. .find('[value=' + $(this).attr('value') + ']')
  81. .prop('selected', 'selected');
  82. });
  83. $.fancybox.close();
  84. });
  85. }
  86. public checkChecked(id) {
  87. return this.selected.hasOwnProperty(id);
  88. }
  89. public on(eventName: string, callback: (responseText: string) => void) {
  90. this.events[eventName].push(callback);
  91. return this;
  92. }
  93. public trigger(eventName: string, ...args: any[]) {
  94. let context = this;
  95. for (let i in this.events[eventName]) {
  96. if (this.events[eventName].hasOwnProperty(i)) {
  97. setTimeout(this.events[eventName][i].apply(context, args), 1);
  98. }
  99. }
  100. }
  101. private populateCheckboxData(checkboxData: ItemInterface[]) {
  102. checkboxData.sort(function (item1: ItemInterface, item2: ItemInterface) {
  103. return item1.value.localeCompare(item2.value);
  104. });
  105. for (let i in checkboxData) {
  106. if (checkboxData.hasOwnProperty(i)) {
  107. if (checkboxData[i].items.length) {
  108. let group = new CheckboxGroup(checkboxData[i], this);
  109. this.checkboxData.push(group);
  110. } else {
  111. let item = new CheckboxItem(checkboxData[i], this);
  112. this.checkboxData.push(item);
  113. }
  114. }
  115. }
  116. }
  117. public render() {
  118. let items = $('<div></div>');
  119. this.checkboxData.forEach(function (item) {
  120. if (item instanceof CheckboxItem) {
  121. let group = $('<div class="fancycheckboxes-group"></div>');
  122. group.append(item.render());
  123. items.append(group);
  124. } else {
  125. items.append(item.render());
  126. }
  127. });
  128. items.find('.fancycheckboxes-group').each(function () {
  129. if ($(this).find('.fancycheckboxes-item').length > 5) {
  130. $(this).append($('<a class="more">Все &raquo;</a>'));
  131. $(this).height(150);
  132. }
  133. });
  134. return items;
  135. }
  136. }
  137. interface ItemInterface {
  138. id: number;
  139. value: string;
  140. items: ItemInterface[];
  141. }
  142. class CheckboxGroup {
  143. public items: any[];
  144. public name: string;
  145. private widget: FancyCheckbox;
  146. public constructor(item: ItemInterface, widget: FancyCheckbox) {
  147. this.widget = widget;
  148. this.name = item.value;
  149. this.items = [];
  150. this.populateCheckboxData(item.items);
  151. }
  152. private populateCheckboxData(checkboxData: ItemInterface[]) {
  153. checkboxData.sort(function (item1: ItemInterface, item2: ItemInterface) {
  154. return item1.value.localeCompare(item2.value);
  155. });
  156. for (let i in checkboxData) {
  157. if (checkboxData.hasOwnProperty(i)) {
  158. if (checkboxData[i].items.length) {
  159. let group = new CheckboxGroup(checkboxData[i], this.widget);
  160. this.items.push(group);
  161. } else {
  162. let item = new CheckboxItem(checkboxData[i], this.widget);
  163. this.items.push(item);
  164. }
  165. }
  166. }
  167. }
  168. public render() {
  169. let group = $('<div class="fancycheckboxes-group"></div>');
  170. group.append($('<h4>' + this.name + '</h4>'));
  171. this.items.forEach(function (item) {
  172. group.append(item.render());
  173. });
  174. return group;
  175. }
  176. }
  177. class CheckboxItem {
  178. public id: number;
  179. public name: string;
  180. private widget: FancyCheckbox;
  181. public constructor(item: ItemInterface, widget: FancyCheckbox) {
  182. this.id = item.id;
  183. this.name = item.value;
  184. this.widget = widget;
  185. }
  186. public render() {
  187. let item = $('<div class="fancycheckboxes-item"></div>');
  188. item.append($('<input type="checkbox" value="' + this.id + '" id="fchb_' + this.id + '" > <label for="fchb_' + this.id + '">' + this.name + '</label>'));
  189. if (this.widget.checkChecked(this.id)) {
  190. item.find('input').attr('checked', 'checked');
  191. }
  192. return item;
  193. }
  194. }
  195. }