/// namespace RegionSelection { function foreach(data, callback: (value: any, key?: number | string, array?: Array) => void) { for (let key in data) { if (data.hasOwnProperty(key) && typeof data[key] !== 'function') { callback(data[key], key, data); } } } class RegionsCollection { [index: number]: Region; public constructor(data: Region[]) { let length = 0; this.setLength = function (value: number) { length = value; }; this.getLength = function () { return length; }; foreach(data, (region: Region) => this.push(region)); } get length() { return this.getLength(); }; set length(value: number) { this.setLength(value); } public setLength(value: number) { }; public getLength(): number { return 0; }; public push(item: Region) { Array.prototype.push.call(this, item); } public forEach(callback: (value: any, key?: number | string, array?: Array) => void) { Array.prototype.forEach.call(this, callback); } public group(groupFunction: (region: Region) => string): { [groupName: string]: RegionsCollection } { let groups = {}; this.forEach((region: Region) => { let groupName = groupFunction(region); if (groups[groupName] === undefined) { groups[groupName] = new RegionsCollection([]); } groups[groupName].push(region); }); return groups; } public sort(sortFunction: (region1: Region, region2: Region) => number): RegionsCollection { let data = []; this.forEach((region) => data.push(region)); data.sort(sortFunction); return new RegionsCollection(data); } } class RegionSelectionBox { private selector: JQuery; private regions: RegionsCollection = new RegionsCollection([]); private box: JQuery; constructor(selector: JQuery) { this.selector = selector; if (this.selector.data('regions') !== undefined) { this.fillRegions(this.selector.data('regions')); } this.selector.on('click', this.showBox.bind(this)); } private fillRegions(data) { foreach(eval(data), (value: RegionInterface) => { this.regions.push(new Region(value)); }); } private showBox(e: JQueryEventObject) { e.preventDefault(); e.stopPropagation(); if (this.box === undefined) { this.renderBox(); } let box = this.box; let hide = function () { box.hide(0, () => { $('body').off('click', hide); }); }.bind(this); if (box.is(':visible')) { hide(); } else { $('body').on('click', hide); box.show(0); } } private renderBox() { if (!$('.region__selection-box').length) { this.box = $('
'); let linkTemplate = '{name}'; // let iconTemplate = ''; let grouped = this.regions.sort(function (region1: Region, region2: Region) { return region1.caption < region2.caption ? -1 : region1.caption > region2.caption ? 1 : 0; }).group((region: Region) => { return region.caption.charAt(0).toUpperCase(); }); foreach(grouped, (regionCollection: RegionsCollection, groupName) => { let itemsList = $('
'); itemsList.append($(`
${groupName}
`)); foreach(regionCollection, (region: Region) => { let item = $('
').append(linkTemplate .replace('{link}', region.link) .replace('{name}', region.caption) // .replace('{icon}', iconTemplate.replace('{icon}', region.icon)) ); itemsList.append($(item)); }); this.box.append(itemsList); }); this.box.css('display', 'none'); this.selector.parent().append(this.box); } } } interface RegionInterface { id: number; caption: string; link: string; icon: string; } class Region { constructor(data: RegionInterface) { this._id = data.id; this._caption = data.caption; this._link = data.link; this._icon = data.icon; } private _id: number; get id() { return this._id; } private _caption: string; get caption() { return this._caption; } private _link: string; get link(): string { return this._link; } private _icon: string; get icon(): string { return this._icon; } } export function createSelectionBox($object: JQuery) { return new RegionSelectionBox($object); } }