c80_map_floors 0.1.0.9 → 0.1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascripts/lib/awesomplete.js +450 -0
- data/app/assets/javascripts/map_objects/area.js +12 -8
- data/app/assets/javascripts/map_objects/building.js +23 -6
- data/app/assets/javascripts/src/main.js +12 -2
- data/app/assets/javascripts/src/state_controller.js +50 -8
- data/app/assets/javascripts/svg_elements/admin_building_label.js +6 -6
- data/app/assets/javascripts/svg_elements/building_label.js +88 -60
- data/app/assets/javascripts/ui/tabs/tabs.js +55 -2
- data/app/assets/javascripts/view/building_info/building_info.js +85 -8
- data/app/assets/javascripts/view/building_info/mobj_info_parser.js +316 -12
- data/app/assets/javascripts/view/search_gui.js +295 -0
- data/app/assets/stylesheets/c80_map_floors.scss +3 -1
- data/app/assets/stylesheets/lib/awesomplete.scss +104 -0
- data/app/assets/stylesheets/lib_custom/awesomplete.scss +8 -0
- data/app/assets/stylesheets/map.scss +61 -16
- data/app/assets/stylesheets/ui/search_gui.scss +51 -0
- data/app/assets/stylesheets/ui/tabs_js.scss +25 -0
- data/app/assets/stylesheets/view/buttons/back_to_map_button.scss +1 -1
- data/app/assets/stylesheets/view/elems/building_info.scss +1 -1
- data/app/assets/stylesheets/view/elems/free_areas_label.scss +6 -1
- data/app/controllers/c80_map_floors/ajax_controller.rb +82 -0
- data/app/helpers/c80_map_floors/search_gui_helper.rb +19 -0
- data/app/models/c80_map_floors/area.rb +1 -1
- data/app/models/c80_map_floors/area_representator.rb +13 -22
- data/app/models/c80_map_floors/building_representator.rb +8 -1
- data/app/models/c80_map_floors/floor.rb +1 -1
- data/app/models/c80_map_floors/map_building.rb +2 -2
- data/app/models/c80_map_floors/map_json.rb +2 -1
- data/app/views/c80_map_floors/_map_row_index.html.erb +5 -0
- data/app/views/c80_map_floors/shared/map_row/_search_gui.html.erb +11 -0
- data/config/routes.rb +2 -0
- data/lib/c80_map_floors/version.rb +1 -1
- metadata +9 -2
@@ -2,32 +2,185 @@
|
|
2
2
|
|
3
3
|
// в задачи этого кода входит преобразование JSON объектов в human-читаемый текст с характеристиками
|
4
4
|
|
5
|
-
|
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
|
-
|
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
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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
|
+
}
|