c80_map_floors 0.1.0.9 → 0.1.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/lib/awesomplete.js +450 -0
  3. data/app/assets/javascripts/map_objects/area.js +12 -8
  4. data/app/assets/javascripts/map_objects/building.js +23 -6
  5. data/app/assets/javascripts/src/main.js +12 -2
  6. data/app/assets/javascripts/src/state_controller.js +50 -8
  7. data/app/assets/javascripts/svg_elements/admin_building_label.js +6 -6
  8. data/app/assets/javascripts/svg_elements/building_label.js +88 -60
  9. data/app/assets/javascripts/ui/tabs/tabs.js +55 -2
  10. data/app/assets/javascripts/view/building_info/building_info.js +85 -8
  11. data/app/assets/javascripts/view/building_info/mobj_info_parser.js +316 -12
  12. data/app/assets/javascripts/view/search_gui.js +295 -0
  13. data/app/assets/stylesheets/c80_map_floors.scss +3 -1
  14. data/app/assets/stylesheets/lib/awesomplete.scss +104 -0
  15. data/app/assets/stylesheets/lib_custom/awesomplete.scss +8 -0
  16. data/app/assets/stylesheets/map.scss +61 -16
  17. data/app/assets/stylesheets/ui/search_gui.scss +51 -0
  18. data/app/assets/stylesheets/ui/tabs_js.scss +25 -0
  19. data/app/assets/stylesheets/view/buttons/back_to_map_button.scss +1 -1
  20. data/app/assets/stylesheets/view/elems/building_info.scss +1 -1
  21. data/app/assets/stylesheets/view/elems/free_areas_label.scss +6 -1
  22. data/app/controllers/c80_map_floors/ajax_controller.rb +82 -0
  23. data/app/helpers/c80_map_floors/search_gui_helper.rb +19 -0
  24. data/app/models/c80_map_floors/area.rb +1 -1
  25. data/app/models/c80_map_floors/area_representator.rb +13 -22
  26. data/app/models/c80_map_floors/building_representator.rb +8 -1
  27. data/app/models/c80_map_floors/floor.rb +1 -1
  28. data/app/models/c80_map_floors/map_building.rb +2 -2
  29. data/app/models/c80_map_floors/map_json.rb +2 -1
  30. data/app/views/c80_map_floors/_map_row_index.html.erb +5 -0
  31. data/app/views/c80_map_floors/shared/map_row/_search_gui.html.erb +11 -0
  32. data/config/routes.rb +2 -0
  33. data/lib/c80_map_floors/version.rb +1 -1
  34. metadata +9 -2
@@ -2,32 +2,185 @@
2
2
 
3
3
  // в задачи этого кода входит преобразование JSON объектов в human-читаемый текст с характеристиками
4
4
 
5
- var MobjInfoParser = function () {
5
+ function MobjInfoParser() {
6
6
 
7
7
  var _this = this;
8
8
 
9
9
  // с помощью этого хелпера можно понять, например, что square это "общая площадь" (типа locales/ru.yml)
10
10
  var _i18n = null;
11
11
 
12
- /** Лабаем html текст из json-данных полигона Этажа/Здания/Площади
12
+ // todo-clear22:: необходимо сбрасывать это значение после того, как сбросили поиск
13
+ // текущий результат поиска - какие полигоны площадей соответствуют поиску и содержат искомые магазины
14
+ var _sresults_areas = null;
15
+
16
+ // используется в _row_area_with_shop() и в _row_area_shop()
17
+ var _row_area_shop_pattern = "<li><a href='{HREF}' title='{TITLE}' target='_blank'>{TITLE}</a> ({AREA_TITLE}), {PHONE}</li>";
18
+
19
+ // используется в _row_area_data()
20
+ var _row_area_pattern = "<li><a href='{HREF}' title='{AREA_TITLE}' target='_blank'>{AREA_TITLE}</a></li>";
21
+
22
+ // режимы отображения данных - user mode. Их два: "режим арендатора" и "режим обычного пользователя"
23
+ var _umode = 'umode_simple_user'; // umode_arendator, umode_simple_user
24
+
25
+ //--[ public ]------------------------------------------------------------------------------------------------------
26
+
27
+ /**
28
+ * Лабаем html текст из json-данных полигона Этажа/Здания/Площади.
13
29
  *
14
30
  * @param json
15
31
  */
16
32
  this.makeHtmlText = function (json) {
17
- console.log("<makeHtmlText> Лабаем html текст из json данных полигона.");
33
+ console.log("<MobjInfoParser.makeHtmlText> Лабаем html текст из json данных полигона.");
18
34
 
19
35
  var result = "";
20
36
 
21
37
  //#-> предполагается, что json в поряде и данные целостны (т.е. уровнем выше была проверка json на корректность)
22
38
  switch (json["class_name"]) {
23
39
  case "C80MapFloors::Floor":
24
- result += _this._row('square', json);
25
- result += _this._row('square_free', json);
26
- result += _this._row('floor_height', json);
27
- result += _this._row('communications', json);
28
- result += _this._row('areas_count', json);
29
- result += _this._row('areas_free_count', json);
30
- result += _this._row('price_string', json);
40
+
41
+ /* [aa34qq] json:
42
+ {
43
+ <...свойства картинки этажа, чисто класс C80MapFloors::Floor..>
44
+
45
+ "areas": [ // полигоны площадей этой картинки этажа
46
+ { "id": 5,
47
+ <...C80MapFloors::Floor..>
48
+
49
+ "data": { // данные привязанной к плоигону Площади
50
+ "id": 9,
51
+ "title": "Дом-1",
52
+ "square": null,
53
+ "desc": "",
54
+ "price_string": null,
55
+ "communications": null,
56
+ "is_free": false,
57
+ "shop": { // данные Магазина, который занимает эту Площадь
58
+ "id": 130,
59
+ "title": "ИП Кибардин",
60
+ "desc": "",
61
+ "tel": "(910) 514 08 68",
62
+ "site": "",
63
+ "url": "/shops/ip-kibardin.html"
64
+ }
65
+ }
66
+ },
67
+ ],
68
+
69
+ "data": // данные Этажа, привязанного к картинке этажа
70
+ "id": 40,
71
+ "ord": 1,
72
+ "title": "1 этаж",
73
+ "square": 0.0,
74
+ "square_free": 0.0,
75
+ "areas_count": 2,
76
+ "areas_free_count": 2,
77
+ "price_string": "от до руб./кв.м",
78
+ "floor_height": null,
79
+ "communications": ""
80
+ }
81
+ }*/
82
+
83
+ /* [aa34qq] или сокращённо
84
+ json:
85
+ {
86
+ "areas": [ // полигоны площадей этой картинки этажа
87
+ { "id": 5,
88
+
89
+ "data": { // данные привязанной к плоигону Площади
90
+ "id": 9,
91
+ "title": "Дом-1",
92
+ "is_free": false,
93
+ "shop": { // данные Магазина, который занимает эту Площадь
94
+ "id": 130,
95
+ "title": "ИП Кибардин",
96
+ }
97
+ }
98
+ },
99
+ ],
100
+
101
+ "data": // данные Этажа, привязанного к картинке этажа
102
+ "id": 40,
103
+ "title": "1 этаж",
104
+ }
105
+ }
106
+ */
107
+
108
+ // при наличии результатов поиска
109
+ if (_sresults_areas != null) {
110
+
111
+ //<editor-fold desc="// посмотрим, нету ли в json полигонов площадей, чьи айдишники перечислены в _sresults_areas">
112
+
113
+ // подготовительно: соберём айдишники полигонов площадей в отдельный массив
114
+ var arr_map_areas_ids = $.map(json['areas'], function (val, index) {
115
+ return val['id'];
116
+ });
117
+
118
+ console.log('<MobjInfoParser.makeHtmlText> В массиве [' + arr_map_areas_ids.join(', ') +'] ищем элементы: [' + _sresults_areas.join(', ') + '].');
119
+
120
+ //<editor-fold desc="// 1. переберём айдишники из _sresults_areas и поищем их в arr_json_areas_ids.">
121
+ /* результат (индексы объектов для отображения из массива json['areas']) соберём в массиве [**] */
122
+
123
+ var i, len = _sresults_areas.length;
124
+ var i_search_index; // индекс айдишника `искомой пользователем полигона площади` в массиве json['areas'] полигонов площадей (просматриваемого этажа)
125
+ var isaid; // iterated searched area's id
126
+ var arr_search_indexes = []; // [**] - индексы объектов полигонов площадей просматриваемого этажа (для отображения в инфо панели) из массива json['areas']
127
+
128
+ for (i=0; i<len; i++) {
129
+ isaid = _sresults_areas[i];
130
+ i_search_index = arr_map_areas_ids.indexOf(isaid);
131
+ // если в map-массиве полигонов площадей просматриваемого этажа обнаружен айдишник `искомой пользователем площади`
132
+ if (i_search_index != -1) {
133
+ console.log('<MobjInfoParser.makeHtmlText> В массиве [' + arr_map_areas_ids.join(', ') +'] обнаружен ' + isaid + '.');
134
+ // запомним каждый i_search_index (затем я намереваюсь обработать их в отдельном цикле: найти соответствующие данные полигонов площадей (просматриваемого этажа) в массиве json['areas'], и собрать html-сроки для каждого объекта с данными в один список
135
+ arr_search_indexes.push(i_search_index);
136
+ }
137
+ }
138
+ //</editor-fold>
139
+
140
+ //<editor-fold desc="// 2. Теперь переберём найденные индексы, собирая по ходу html-строки для отображения">
141
+
142
+ len = arr_search_indexes.length;
143
+ // если на этаже есть площади, удовлетворяющие поиску
144
+ if (len > 0) {
145
+ var i_json_area;
146
+ // переберём индексы
147
+ for (i=0; i<len; i++) {
148
+
149
+ // зафиксируем индекс и соотв. данные
150
+ i_search_index = arr_search_indexes[i];
151
+ i_json_area = json['areas'][i_search_index];
152
+
153
+ //#-> если всё в порядке (есть данные полигона площади по этому индексу) - лабаем из них html-строку
154
+ if (i_json_area != undefined) {
155
+ result += _this._row_area_with_shop(i_json_area);
156
+ }
157
+
158
+ // иначе - сообщим об ошибке в лог
159
+ else {
160
+ console.log('<MobjInfoParser.makeHtmlText> [ERROR] Вроде индекс есть ('+i_search_index+'), а данных по этому адресу не нашлось...');
161
+ }
162
+ }
163
+ }
164
+
165
+ // если же на этаже нету результатов, удовлетворяющих поиску
166
+ else {
167
+ // "просто отобразим данные об этаже согласно режиму"
168
+ result = _this._makeHtmlText_Umode_Floor(json);
169
+ }
170
+
171
+
172
+ //</editor-fold>
173
+
174
+ //</editor-fold>
175
+
176
+ }
177
+
178
+ // если это не поиск
179
+ else {
180
+ // "просто отобразим данные об этаже согласно режиму"
181
+ result = _this._makeHtmlText_Umode_Floor(json);
182
+ }
183
+
31
184
  break;
32
185
  }
33
186
 
@@ -36,6 +189,96 @@ var MobjInfoParser = function () {
36
189
 
37
190
  };
38
191
 
192
+ /**
193
+ * Задаём текущие результаты поиска (вызывается из BuildingInfo).
194
+ * @param sresult_areas
195
+ */
196
+ this.setSearchResultAreas = function (sresult_areas) {
197
+ _sresults_areas = sresult_areas;
198
+ };
199
+
200
+ /** Извне задаём текущий режим просмотра данных.
201
+ *
202
+ * @param umode
203
+ */
204
+ this.setUmode = function (umode) {
205
+ _umode = umode;
206
+ };
207
+
208
+ //--[ private ]-----------------------------------------------------------------------------------------------------
209
+
210
+ /**
211
+ * На основе режима пользователя карты (Арендатор или ОбычныйПокупатель) выдать html-строку с `просто данными` об Этаже.
212
+ *
213
+ * @param json_floor - данные полигона этажа от C80MapFloors::Floor.my_as_json (пример можно лицезреть в [aa34qq]
214
+ * @returns {string} - html-строка, которая завернётся в <ul>...</ul>
215
+ * @private
216
+ */
217
+ this._makeHtmlText_Umode_Floor = function (json_floor) {
218
+
219
+ var result = '';
220
+
221
+ // todo-umode:: внедрить и использовать режим пользователя карты (Арендатор или ОбычныйПокупатель) и соответствующим образом отрисовать `просто данные` об Этаже
222
+
223
+ if (_umode == 'umode_arendator') {
224
+ //<editor-fold desc=" // отобразим данные Этажа: метраж, кол-во площадей, коммуникации, цена за кв.м (режим Арендатора)">
225
+ result += _this._row('square', json_floor);
226
+ result += _this._row('square_free', json_floor);
227
+ //result += _this._row('floor_height', json);
228
+ result += _this._row('communications', json_floor);
229
+ result += _this._row('areas_count', json_floor);
230
+ result += _this._row('areas_free_count', json_floor);
231
+ result += _this._row('price_string', json_floor);
232
+ //</editor-fold>
233
+ }
234
+
235
+ else if (_umode == 'umode_simple_user') {
236
+
237
+ // отобразим всех арендаторов на этом этаже
238
+
239
+ var areas = json_floor['areas'];
240
+ if (areas != null) {
241
+
242
+ var len = areas.length;
243
+ var i, iar, iard; // i_area, i_area_data
244
+
245
+ for (i=0; i<len; i++) {
246
+
247
+ // фиксируем данные полигона площади
248
+ iar = areas[i];
249
+ // фиксируем данные Площади, которая привязана к полигону
250
+ iard = iar['data'];
251
+
252
+ // если имеются данные Площади - работаем дальше (т.е. на выходе из if полюбому будет добавлена строка)
253
+ if (iard != null) {
254
+
255
+ // если имеются данные о Магазине (т.е. если есть Магазин, занимающий эту Площадь)
256
+ if (iard['shop'] != null) {
257
+ // соорудим строку, которая описывает этот Магазин
258
+ result += _this._row_area_shop(iar);
259
+ }
260
+
261
+ // если же нет данных о Магазине (т.е. Площадь свободна)
262
+ else {
263
+ // соорудим строку, которая описывает эту Площадь
264
+ result += _this._row_area_data(iard);
265
+ }
266
+ }
267
+
268
+ }
269
+ }
270
+ }
271
+
272
+ return result;
273
+ };
274
+
275
+ /**
276
+ * Соорудить html-строку для списка свойств Этажа.
277
+ * @param key
278
+ * @param json
279
+ * @returns {string}
280
+ * @private
281
+ */
39
282
  this._row = function (key, json) {
40
283
  var s = '';
41
284
  if (key == 'price_string') {
@@ -46,6 +289,68 @@ var MobjInfoParser = function () {
46
289
  return s;
47
290
  };
48
291
 
292
+ /**
293
+ * Соорудить html-строку, описывающую только Площадь (согласно паттерну _row_area_pattern).
294
+ * Т.е. даже если есть Магазин, занимающий эту Площадь - он не будет браться в рассчёт.
295
+ *
296
+ * Нет защиты от ошибок (это значит, что этот метод должен использоваться в if..else конструкции,
297
+ * которая проверяет наличие необходимых данных).
298
+ *
299
+ * @param area_data_json - это узел 'data' объекта, описывающего полигон площади.
300
+ * @private
301
+ */
302
+ this._row_area_data = function (area_data_json) {
303
+ var res = _row_area_pattern;
304
+ res = res.split('{HREF}').join('#'); // todo:: какой должен быть href у свободной Площади?
305
+ res = res.split('{AREA_TITLE}').join(area_data_json['title']);
306
+ return res;
307
+ };
308
+
309
+ /**
310
+ * Этот служебный метод является контейнером кода, который желательно использовать только в makeHtmlText.
311
+ * Выдать человекочитаемую html-строку <li>...</li>, которая описывает искомый Магазин.
312
+ * Т.к. ВСЕГДА в таком случае ожидается наличие магазина - то в случае ошибки результат будет содержать
313
+ * сообщение об ошибке.
314
+ *
315
+ * @param area_json - данные об полигоне площади, сформированные методом C80MapFloors::Area.my_as_json4
316
+ * @returns {string} - <li><a href='' title='' target='_blank'>Магазин такой-то</a>(площадь такая-то), телефоны<li>
317
+ * @private
318
+ *
319
+ */
320
+ this._row_area_with_shop = function (area_json) {
321
+ var res = '<li>[ERROR] Нет данных о магазине в полигоне площади с id='+area_json['id']+'</li>';
322
+ if (area_json['data'] != undefined && area_json['data']['shop'] != undefined) {
323
+ res = _this._row_area_shop(area_json);
324
+ }
325
+ return res;
326
+ };
327
+
328
+ /**
329
+ * Соорудить строку, описывающую Магазин (согласно паттерну _row_area_shop_pattern).
330
+ *
331
+ * На вход подаётся json полигона площади.
332
+ * Нет защиты от ошибок (это значит, что этот метод должен использоваться в if..else конструкции,
333
+ * которая проверяет наличие необходимых данных)..
334
+ *
335
+ * Метод (контейнер кода) родился из метода _row_area_with_shop, когда начали внедрять режим _umode
336
+ * и расширять функционал _makeHtmlText_Umode_Floor.
337
+ *
338
+ * @param area_json
339
+ * @returns {string}
340
+ * @private
341
+ */
342
+ this._row_area_shop = function (area_json) {
343
+ var shop = area_json['data']['shop'];
344
+ var res = _row_area_shop_pattern;
345
+ res = res.split('{TITLE}').join(shop['title']);
346
+ res = res.split('{HREF}').join(shop['url']);
347
+ res = res.split('{PHONE}').join(shop['tel']);
348
+ res = res.split('{AREA_TITLE}').join(area_json['data']['title']);
349
+ return res;
350
+ };
351
+
352
+ //--[ init ]--------------------------------------------------------------------------------------------------------
353
+
49
354
  var _fInit = function () {
50
355
 
51
356
  // кастуем locales-помощника
@@ -54,5 +359,4 @@ var MobjInfoParser = function () {
54
359
  };
55
360
 
56
361
  _fInit();
57
- };
58
-
362
+ }
@@ -0,0 +1,295 @@
1
+ "use strict";
2
+
3
+ //----------------------------------------------------------------------------------------------------------------------
4
+ //
5
+ // На экране присутствует div#search_gui, в котором содержится форма поиска (поле ввода и кнопка).
6
+ // SearchGUI обслуживает этот див, а именно:
7
+ // - позволяет управлять видимостью,
8
+ // - позволяет двигать его РОДИТЕЛЯ так, чтобы он не загораживался ничем при смене состояния приложения,
9
+ // - отправляет поисковые запросы на сервер и принимает ответы,
10
+ // - парсит ответы,
11
+ // - и содержит публичный метод, подсвечивающий результаты поиска (полигоны) на карте и табы в инфо-панели
12
+ //
13
+ //----------------------------------------------------------------------------------------------------------------------
14
+
15
+ function SearchGUI(link_to_map) {
16
+
17
+ var _this = this;
18
+ var _map = null; // ссылка на класс карты
19
+ var _$container = null; // родительский див (добавлен только для того, чтобы можно было двигать форму при смене состояния приложения)
20
+ var _$search_gui = null; // ссылка на обслуживаемый div с формой
21
+ var _$input = null; // поле ввода (сюда юзер вводит искомый текст)
22
+ var _$submit = null; // кнопка "найти"
23
+ var _current_search_results = null; // текущие результаты поиска
24
+ var _counter = 0; // счётчик отправленных запросов
25
+ var _$reset_btn = null; // ссылка/кнопка "сбросить результаты поиска"
26
+
27
+ //--[ public ]------------------------------------------------------------------------------------------------------
28
+
29
+ /**
30
+ * На основе текущих результатов поиска и
31
+ * в зависимости от текущего состояния приложения
32
+ * метод подсвечивает полигоны на карте и табы в инфо-панели
33
+ *
34
+ */
35
+ this.handleSearchResults = function () {
36
+ if (_current_search_results != null) {
37
+ console.log('<SearchGUI.handleSearchResults> Подсветим результаты поиска.');
38
+
39
+ //<editor-fold desc="// подсветим полигоны на карте...">
40
+ var s = _map.svg;
41
+ var c = s.children();
42
+ var l = c.length;
43
+ var i, ig, igobj, imbid, imaid; // <i_map_building_id>, <i_map_area_id>
44
+ var imb; // <i_map_buidling>
45
+ var iindex; // индекс (айдишника полигона здания) в массиве (полигонов зданий, удовлетворающих поиску)
46
+ var ibscount; // <i_buildings_shops_count>
47
+
48
+ for (i=0; i<l; i++) {
49
+ ig = s[0].children[i]; // именно [0]
50
+ //console.log(ig['obj']); // => Polygon
51
+ if (ig != undefined) { // такое тоже бывает
52
+ if (ig['obj'] != undefined) {
53
+ igobj = ig['obj'];
54
+ //console.log('[breakpoint]');
55
+
56
+ // добираемся до класса Building.js
57
+ if (ig['obj']['building'] != undefined) {
58
+ //console.log("Полигон здания: " + ig['obj']['building'].id); => Полигон здания: 10
59
+
60
+ imb = ig['obj']['building'];
61
+ imbid = imb.id;
62
+ iindex = _current_search_results['buildings'].indexOf(imbid);
63
+
64
+ //#-> если в результатах поиска присутствует перебираемый map_building_id - полигону добавим класс 'found'
65
+ if (iindex != -1) {
66
+ console.log('<SearchGUI.handleSearchResults> addClass "found" на полигон здания imdid=' + imbid);
67
+ $(ig).find('polygon').addClass('found');
68
+
69
+ // и зажгём лейбл с подсказкой
70
+ ibscount = _current_search_results['buildings_shops_count'][iindex];
71
+ imb.greenCircleShow(ibscount);
72
+ }
73
+
74
+ //#-> иначе - удалим (возможный) класс `found` и скроем (возможный) лейбл с подсказкой
75
+ else {
76
+ $(ig).find('polygon').removeClass('found');
77
+ imb.greenCircleHide();
78
+ }
79
+
80
+ }
81
+
82
+ // добираемся до класса Area.js
83
+ else if (ig['obj']['area'] != undefined) {
84
+ imaid = ig['obj']['area'].id;
85
+
86
+ // если в результатах поиска присутствует перебираемый map_area_id - полигону добавим класс 'found_area'
87
+ if (_current_search_results['areas'].indexOf(imaid) != -1) {
88
+ console.log('<SearchGUI.handleSearchResults> addClass "found_area" на полигон площади imaid=' + imaid);
89
+ $(ig).find('polygon').addClass('found_area');
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ }
96
+ //</editor-fold>
97
+
98
+ // подсветим вкладки этажей в инфопанели
99
+ _map.building_info_klass.searchResultsShow(_current_search_results);
100
+ }
101
+ };
102
+
103
+ /**
104
+ * Вернуть родительский div-контейнер в начальную (исходную, `нормальную`) позицию.
105
+ */
106
+ this.position_init = function () {
107
+ // если еще ниразу никуда не сдвигали с начальной позиции
108
+ if (_$container.data('init_position_top') == undefined) {
109
+ // запомним начальную позицию
110
+ _$container.data('init_position_top', _$container.css("top"));
111
+ _$container.data('init_position_left', _$container.css("left"));
112
+ }
113
+ _$container.css("top", _$container.data('init_position_top'));
114
+ _$container.css("left", _$container.data('init_position_left'));
115
+ };
116
+
117
+ /**
118
+ * Установить div-контейнер чуть левее исходной позиции так, чтобы инфо-панель не загораживала форму поиска.
119
+ * Используется при переходе в режимы, где видна инфо-панель: внутри здания, например. Или внутри этажа.
120
+ */
121
+ this.position_inside = function () {
122
+ //console.log('<position_inside> [breakpoint].');
123
+ _$container.css("left", -200);
124
+ _$container.css("top", _$container.data('init_position_top'));
125
+ };
126
+
127
+ /**
128
+ * Спрятать контейнер (задвинуть его за пределы экрана).
129
+ * Например, когда переходим в режим редактирования.
130
+ */
131
+ this.position_hide = function () {
132
+ _$container.css("top", -200);
133
+ };
134
+
135
+ //--[ private ]-----------------------------------------------------------------------------------------------------
136
+
137
+ /**
138
+ * Отправляем запрос с текстом для поиска на сервер.
139
+ *
140
+ * @param stext - название категории, которой должны соответствовать арендаторы
141
+ * @private
142
+ */
143
+ this._sendSearchRequest = function (stext) {
144
+ console.log('<_sendSearchRequest> Отправляем поисковый запрос на сервер: stext = ' + stext);
145
+
146
+ // покажем прелоадер
147
+ _map.save_preloader_klass.show();
148
+
149
+ // todo-search: реализовать проверку "слишком короткий текст, не отправляем" тут (перенести проверку из _submitOnClick)
150
+ // todo-search: реализовать проверку "такая строка только что отправлялась и текущие результаты по ней содержатся в _current_search_results)
151
+
152
+ // увеличим счётчик запросов
153
+ _counter = _counter + 1;
154
+
155
+ // отправим запрос на сервер
156
+ $.ajax({
157
+ url: '/ajax/find_shops',
158
+ type: 'POST',
159
+ data: {
160
+ stext: stext,
161
+ counter: _counter
162
+ },
163
+ dataType: 'json'
164
+ }).done(_this._sendSearchRequestDone);
165
+
166
+ };
167
+
168
+ /**
169
+ * Получили [какой-то] ответ от сервера на запрос о поиске.
170
+ *
171
+ * @param data - результат поиска (внутри метода в комментах пример ответа)
172
+ * @param result
173
+ * @private
174
+ */
175
+ this._sendSearchRequestDone = function (data, result) {
176
+ console.log('<_sendSearchRequestDone> Получили [какой-то] ответ от сервера на запрос о поиске:');
177
+
178
+ //console.log(data);
179
+ // {
180
+ // buildings: [7,10],
181
+ // floors: [2,6,40],
182
+ // areas: [3,5,8,6]
183
+ //}
184
+
185
+ // один из вариантов (unused)
186
+ //{
187
+ // buildings: [
188
+ // { id: 7,
189
+ // floors: [
190
+ // { id: 2,
191
+ // areas: [3]
192
+ // }
193
+ // ]
194
+ // },
195
+ // {
196
+ // id: 10,
197
+ // floors: [
198
+ // { id: 6,
199
+ // areas: [5,8]
200
+ // },
201
+ // { id: 48,
202
+ // areas: [6]
203
+ // }
204
+ // ]
205
+ // }
206
+ // ]
207
+ //}
208
+
209
+ _current_search_results = data;
210
+
211
+ // скроем прелоадер
212
+ _map.save_preloader_klass.hide();
213
+
214
+ // покажем кнопку "сбросить результаты поиска"
215
+ _$reset_btn.css('display', 'block');
216
+
217
+ // обработаем результаты поиска
218
+ _this.handleSearchResults();
219
+
220
+ };
221
+
222
+ /**
223
+ * Нажали на кнопку "найти". -> Отправляем запрос на сервер.
224
+ *
225
+ * @param e
226
+ * @private
227
+ */
228
+ var _submitOnClick = function (e) {
229
+ e.preventDefault();
230
+ var search_text = _$input.val();
231
+ if (search_text.length > 2) {
232
+ console.log('<_submitOnClick> Нажали на кнопку "найти", отправляем текст "' + search_text + '" на поиск.');
233
+ _this._sendSearchRequest(search_text);
234
+ } else {
235
+ console.log('<_submitOnClick> Нажали на кнопку "найти", но искать нечего...');
236
+ }
237
+ };
238
+
239
+ /**
240
+ * Нажали на кнопку "сбросить результаты поиска".
241
+ *
242
+ * @param e
243
+ * @private
244
+ */
245
+ var _resetOnClick = function (e) {
246
+ e.preventDefault();
247
+
248
+ // "обнуляем" результаты поиска (пустые массивы разойдутся в подклассы и там все переменные почистятся)
249
+ // NOTE:: если в AjaxController.find_shops поменяется вид объекта с результатами поиска - то его надо будет поменять и тут
250
+ _current_search_results['buildings'] = [];
251
+ _current_search_results['buildings_shops_count'] = [];
252
+ _current_search_results['floors'] = [];
253
+ _current_search_results['floors_shops_count'] = [];
254
+ _current_search_results['areas'] = [];
255
+
256
+ // очищаем поле ввода
257
+ _$input.val('');
258
+
259
+ // прячем саму кнопку "сбросить результаты поиска"
260
+ _$reset_btn.css('display', 'none');
261
+
262
+ // обработаем пустые результаты поиска
263
+ _this.handleSearchResults();
264
+
265
+ };
266
+
267
+ //--[ init ]--------------------------------------------------------------------------------------------------------
268
+
269
+ var _init = function (link_to_map) {
270
+ console.log('<SearchGUI.init>');
271
+
272
+ _map = link_to_map;
273
+
274
+ // найдём обслуживаемый div
275
+ _$search_gui = $('div#search_gui');
276
+ if (_$search_gui.length > 0) { // работать будем только тогда, когда элемент имеется
277
+
278
+ // зафиксируем элементы
279
+ _$container = $('div.container#search_container'); // зафиксируем родителя
280
+ _$input = _$search_gui.find('input.form-control');
281
+ _$submit = _$search_gui.find('button.btn');
282
+ _$reset_btn = _$container.find('a.reset');
283
+
284
+ // при клике по кнопке 'submit' - отправим текст на сервер, заблокируем форму поиска, сгенерим событие
285
+ _$submit.on('click', _submitOnClick);
286
+
287
+ // при клике по кнопке 'reset' - сбросим текущие результаты поиска
288
+ _$reset_btn.on('click', _resetOnClick);
289
+ }
290
+
291
+ };
292
+
293
+ _init(link_to_map);
294
+
295
+ }