c80_map_floors 0.1.0.1 → 0.1.0.2
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/buttons/admin_buttons/button_area_link.js +2 -2
- data/app/assets/javascripts/buttons/admin_buttons/button_building_link.js +2 -2
- data/app/assets/javascripts/buttons/admin_buttons/button_cancel_create.js +1 -1
- data/app/assets/javascripts/buttons/admin_buttons/button_cancel_remove.js +1 -1
- data/app/assets/javascripts/buttons/admin_buttons/button_complete_create.js +1 -1
- data/app/assets/javascripts/buttons/admin_buttons/button_edit.js +1 -1
- data/app/assets/javascripts/buttons/admin_buttons/button_new.js +1 -1
- data/app/assets/javascripts/buttons/admin_buttons/button_remove.js +1 -1
- data/app/assets/javascripts/c80_map_floors.js.coffee +2 -1
- data/app/assets/javascripts/events/app_event.js +1 -1
- data/app/assets/javascripts/map_objects/area.js +2 -2
- data/app/assets/javascripts/map_objects/building.js +58 -19
- data/app/assets/javascripts/map_objects/dot.js +1 -1
- data/app/assets/javascripts/src/main.js +26 -10
- data/app/assets/javascripts/src/state_controller.js +1 -1
- data/app/assets/javascripts/src/utils/map_utils.js +2 -2
- data/app/assets/javascripts/ui/tabs/tabs.js +191 -0
- data/app/assets/javascripts/view/building_info/building_info.js +117 -0
- data/app/models/c80_map_floors/floor.rb +14 -5
- data/app/views/c80_map_floors/shared/map_row/_building_info.html.erb +6 -16
- data/app/views/c80_map_floors/shared/map_row/_building_info_old.html.erb +17 -0
- data/lib/c80_map_floors/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6acbfc5688ec8e6b14430cc033efc22aecd3367c
|
4
|
+
data.tar.gz: a5e9b23bf22b43fd8ef7c1df5c6d07edad1336a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df5dd1c8a930be07ac3078171fdb989b149f5fd9d7c7971cd1c2db4460eaccbb21d477fa4594c4efdcc231f721ce9e1c3169bbbf33e4358a8a1ae0effa5adaf8
|
7
|
+
data.tar.gz: 47b31d1c1d37dba45c2eee482da8fce399a9b3018b77e43bd27e8b43c0e21b5309465a97f34c8acbded1d4a147021d131f2bbdc5fa3c7e5d166919310158b216
|
@@ -59,7 +59,7 @@ function AreaLinkButton() {
|
|
59
59
|
if (_this.el.hasClass('disabled')) return;
|
60
60
|
e.preventDefault();
|
61
61
|
|
62
|
-
console.log("<AreaLinkButton.click>");
|
62
|
+
//console.log("<AreaLinkButton.click>");
|
63
63
|
|
64
64
|
_map.save_preloader_klass.show();
|
65
65
|
|
@@ -84,7 +84,7 @@ function AreaLinkButton() {
|
|
84
84
|
};
|
85
85
|
|
86
86
|
_this.show = function () {
|
87
|
-
console.log("<AreaLinkButton.show>");
|
87
|
+
//console.log("<AreaLinkButton.show>");
|
88
88
|
_this.el.css('display','block');
|
89
89
|
};
|
90
90
|
|
@@ -59,7 +59,7 @@ function BuildingLinkButton() {
|
|
59
59
|
if (_this.el.hasClass('disabled')) return;
|
60
60
|
e.preventDefault();
|
61
61
|
|
62
|
-
console.log("<BuildingLinkButton.click>");
|
62
|
+
//console.log("<BuildingLinkButton.click>");
|
63
63
|
|
64
64
|
_map.save_preloader_klass.show();
|
65
65
|
|
@@ -84,7 +84,7 @@ function BuildingLinkButton() {
|
|
84
84
|
};
|
85
85
|
|
86
86
|
_this.show = function () {
|
87
|
-
console.log("<BuildingLinkButton.show>");
|
87
|
+
//console.log("<BuildingLinkButton.show>");
|
88
88
|
_this.el.css('display','block');
|
89
89
|
};
|
90
90
|
|
@@ -10,7 +10,7 @@ function CancelRemoveButton() {
|
|
10
10
|
if (_this.el.hasClass('disabled')) return;
|
11
11
|
e.preventDefault();
|
12
12
|
|
13
|
-
console.log("<CancelRemoveButton.onClick> Выходим из режима удаления полигона.");
|
13
|
+
//console.log("<CancelRemoveButton.onClick> Выходим из режима удаления полигона.");
|
14
14
|
_map.setMode('editing');
|
15
15
|
|
16
16
|
};
|
@@ -19,7 +19,7 @@ function EditButton() {
|
|
19
19
|
if (mark_change_only_inner_state == undefined) {
|
20
20
|
mark_change_only_inner_state = false;
|
21
21
|
}
|
22
|
-
console.log("<EditButton.setState> state = " + state);
|
22
|
+
//console.log("<EditButton.setState> state = " + state);
|
23
23
|
|
24
24
|
// этот код коррелирует с [x9cs7]
|
25
25
|
_this.state = state;
|
@@ -32,7 +32,7 @@ function NewButton() {
|
|
32
32
|
if (_this.state == 'creating') {
|
33
33
|
_this.setState('editing');
|
34
34
|
} else {
|
35
|
-
console.log("<NewButton.onClick> Переходим в режим создания полигона.");
|
35
|
+
//console.log("<NewButton.onClick> Переходим в режим создания полигона.");
|
36
36
|
_this.setState('creating');
|
37
37
|
}
|
38
38
|
};
|
@@ -10,7 +10,7 @@ function RemoveButton() {
|
|
10
10
|
if (_this.el.hasClass('disabled')) return;
|
11
11
|
e.preventDefault();
|
12
12
|
|
13
|
-
console.log("<RemoveButton.onClick> Переходим в режим удаления полигона.");
|
13
|
+
//console.log("<RemoveButton.onClick> Переходим в режим удаления полигона.");
|
14
14
|
_map.setMode('removing');
|
15
15
|
|
16
16
|
};
|
@@ -13,8 +13,9 @@
|
|
13
13
|
|
14
14
|
#= require_directory ./events
|
15
15
|
#= require_directory ./map_objects
|
16
|
-
#=
|
16
|
+
#= require_tree ./view
|
17
17
|
#= require_tree ./buttons
|
18
|
+
#= require_tree ./ui
|
18
19
|
|
19
20
|
#= require ./src/utils/utils.js
|
20
21
|
#= require ./src/utils/opacity_buttons_utils.js
|
@@ -107,7 +107,7 @@ function Area() {
|
|
107
107
|
};
|
108
108
|
|
109
109
|
_this.enter = function () {
|
110
|
-
console.log("<Area.enter>");
|
110
|
+
//console.log("<Area.enter>");
|
111
111
|
//clog(_this._options);
|
112
112
|
|
113
113
|
/* рассчитаем масштаб, при котором можно вписать прямоугольник дома в прямоугольник рабочей области */
|
@@ -159,7 +159,7 @@ function Area() {
|
|
159
159
|
};
|
160
160
|
|
161
161
|
_this.exit = function () {
|
162
|
-
console.log('<Area.exit>');
|
162
|
+
//console.log('<Area.exit>');
|
163
163
|
};
|
164
164
|
|
165
165
|
this.invalidateAnimationMask = function () {
|
@@ -7,6 +7,8 @@ function Building() {
|
|
7
7
|
var _options = null;
|
8
8
|
var _polygon = null;
|
9
9
|
|
10
|
+
// хэш с данными об этажах
|
11
|
+
var _data_floors = {};
|
10
12
|
|
11
13
|
// экранные координаты левой верхней точки, куда надо вписать полигон здания
|
12
14
|
//var _left_page_x = 342;
|
@@ -100,7 +102,7 @@ function Building() {
|
|
100
102
|
]
|
101
103
|
}*/
|
102
104
|
var _draw_floor = function (the_floor) {
|
103
|
-
console.log('<Building._draw_floor>');
|
105
|
+
//console.log('<Building._draw_floor>');
|
104
106
|
|
105
107
|
// это тот самый код, который остался без изменений с версии c80_map (прошлой версии)
|
106
108
|
if (the_floor["img_overlay"]["url"] != "null") {
|
@@ -108,21 +110,37 @@ function Building() {
|
|
108
110
|
}
|
109
111
|
if (the_floor["img_bg"]["url"] != "null") {
|
110
112
|
|
111
|
-
//
|
113
|
+
// NOTE::картинку этажа рисуем не по bounding box здания, а по значениям из базы
|
114
|
+
|
115
|
+
// сначала возьём координаты coords_img здания
|
112
116
|
var tmp = _options["coords_img"].split(",");
|
113
|
-
var xx = tmp[0];
|
114
|
-
var yy = tmp[1];
|
117
|
+
var xx = parseFloat(tmp[0]);
|
118
|
+
var yy = parseFloat(tmp[1]);
|
119
|
+
|
120
|
+
// и сложим их с корректирующими координатами coords этажа
|
121
|
+
var xx2 = 0;
|
122
|
+
var yy2 = 0;
|
123
|
+
if (the_floor["coords"].length) {
|
124
|
+
var tmp2 = the_floor["coords"].split(',');
|
125
|
+
xx2 = parseInt(tmp2[0]);
|
126
|
+
yy2 = parseInt(tmp2[1]);
|
127
|
+
}
|
128
|
+
|
129
|
+
// сначала попросим карту очистить слой с img_bg картинками
|
130
|
+
_map.clear_all_map_object_image_bg();
|
115
131
|
|
116
132
|
// просим карту нарисовать картинку с данными характеристиками
|
117
133
|
_image_bg = _map.draw_map_object_image_bg(the_floor["img_bg"]["url"], {
|
118
134
|
//x: _bbox.xmin,
|
119
135
|
//y: _bbox.ymin,
|
120
|
-
x: xx,
|
121
|
-
y: yy,
|
136
|
+
x: xx + xx2,
|
137
|
+
y: yy + yy2,
|
122
138
|
width: the_floor["img_bg_width"],
|
123
139
|
height: the_floor["img_bg_height"]
|
124
140
|
}/*, 'building'*/);
|
125
141
|
|
142
|
+
} else {
|
143
|
+
alert('[ERROR] У этажа нет картинки.');
|
126
144
|
}
|
127
145
|
|
128
146
|
// просим карту нарисовать площади
|
@@ -133,10 +151,13 @@ function Building() {
|
|
133
151
|
// options_floors - as_json массива этажей модели C80MapFloors::Floor
|
134
152
|
var _parse_floors = function (options_floors) {
|
135
153
|
|
136
|
-
//
|
137
|
-
var
|
138
|
-
|
139
|
-
|
154
|
+
// соберём в удобный хэш
|
155
|
+
var i, ifloor_json, ifloor_id;
|
156
|
+
for (i = 0; i < options_floors.length; i++) {
|
157
|
+
ifloor_json = options_floors[i];
|
158
|
+
ifloor_id = ifloor_json["id"];
|
159
|
+
_data_floors[ ifloor_id ] = ifloor_json;
|
160
|
+
}
|
140
161
|
|
141
162
|
};
|
142
163
|
|
@@ -188,32 +209,50 @@ function Building() {
|
|
188
209
|
//console.log("<Building.enter>");
|
189
210
|
//console.log(_options);
|
190
211
|
|
191
|
-
|
212
|
+
// отдадим информацию о C80MapFloors::MapBuilding в панель
|
213
|
+
_map.building_info_klass.setData(_options);
|
192
214
|
|
215
|
+
_zoomToMe();
|
193
216
|
|
194
|
-
setTimeout(function () {
|
217
|
+
//setTimeout(function () {
|
195
218
|
|
196
219
|
// попросим изменить состояние окружающей среды
|
197
220
|
_map.setMode('view_building');
|
198
221
|
|
199
|
-
// попросим показать информацию о Rent::Building здании (привязанному к данному C80MapFloors::MapBuilding)
|
200
|
-
//_map.showBuildingInfo(_options["rent_building_hash"]);
|
201
|
-
|
202
222
|
// запустим внутренний механизм парсинга этажей и их отрисовки
|
203
223
|
_proccess_floors_data();
|
204
224
|
|
205
|
-
}, 400);
|
225
|
+
//}, 400);
|
206
226
|
|
207
227
|
_map.svgRemoveAllNodes();
|
208
228
|
|
209
|
-
_map.current_building = _this;
|
210
229
|
//console.log("<Building.enter> id: " + _this.id);
|
211
230
|
_map.mark_virgin = false;
|
212
231
|
|
232
|
+
//
|
233
|
+
_map.building_info_klass.setSelectedFloor(0);
|
234
|
+
|
213
235
|
};
|
214
236
|
|
237
|
+
/**
|
238
|
+
* Войти на этаж здания.
|
239
|
+
* @param floor_id
|
240
|
+
*/
|
241
|
+
_this.enterFloor = function (floor_id) {
|
242
|
+
console.log('<Building.enterFloor> floor_id: ' + floor_id);
|
243
|
+
|
244
|
+
var flr = _data_floors[floor_id];
|
245
|
+
if (flr != undefined) {
|
246
|
+
_draw_floor(flr);
|
247
|
+
} else {
|
248
|
+
alert('[Buidling.EnterFloor] error: Нет данных об этаже floor_id='+floor_id+'.');
|
249
|
+
}
|
250
|
+
|
251
|
+
|
252
|
+
}
|
253
|
+
|
215
254
|
_this.exit = function () {
|
216
|
-
_image_bg.remove();
|
255
|
+
if (_image_bg != null) _image_bg.remove();
|
217
256
|
if (_image_overlay != null) {
|
218
257
|
_image_overlay.remove();
|
219
258
|
}
|
@@ -267,7 +306,7 @@ function Building() {
|
|
267
306
|
//xmin + "," + ymin + "; " + xmax + "," + ymax +
|
268
307
|
//"; center logical: " + _cx + "," + _cy + ", center screen: " + _map.rightX(_cx) + ", " + _map.rightY(_cy));
|
269
308
|
|
270
|
-
console.log('<Building._calcBBox> ' + xmin + ', ' + ymin);
|
309
|
+
//console.log('<Building._calcBBox> ' + xmin + ', ' + ymin);
|
271
310
|
};
|
272
311
|
|
273
312
|
// при редактировании здания (т.е. изменении полигонов и holer-ов площадей)
|
@@ -90,6 +90,7 @@ var clog = function () {
|
|
90
90
|
self.save_preloader_klass = null;
|
91
91
|
self.last_clicked_g = null; // начали просматривать area\building (запустили сессию), и здесь храним ссылку на последний кликнутый полигон из svg_overlay в течение сессии
|
92
92
|
self.dnd_enable = null; // если да, то можно карту dnd мышкой
|
93
|
+
self.building_info_klass = null; // класс, занимающися отображением данных об этаже\здании\площади
|
93
94
|
|
94
95
|
// во время анимации каждый шаг рассчитывается мгновенный scale
|
95
96
|
self.scale_during_animation = null;
|
@@ -264,14 +265,23 @@ var clog = function () {
|
|
264
265
|
|
265
266
|
});
|
266
267
|
|
267
|
-
//
|
268
|
+
// драг энд дроп и прочая мышь
|
268
269
|
initAddControls();
|
269
270
|
|
271
|
+
// NOTE:: запускаем данные в карту
|
270
272
|
self.draw_childs(data["buildings"]);
|
271
273
|
|
274
|
+
// проверим, всё ли уместилось
|
272
275
|
self.ivalidateViewArea();
|
273
276
|
|
274
|
-
//
|
277
|
+
// инициализиуем класс, занимающийся отображением данных о здании\этаже\площади
|
278
|
+
self.building_info_klass = new BuildingInfo({
|
279
|
+
onFloorTabChange: function (floor_id) {
|
280
|
+
self.current_building.enterFloor(floor_id);
|
281
|
+
}
|
282
|
+
});
|
283
|
+
|
284
|
+
// начнём слушать окно браузера
|
275
285
|
$(window).resize(function () {
|
276
286
|
|
277
287
|
// Mobile
|
@@ -363,6 +373,7 @@ var clog = function () {
|
|
363
373
|
|
364
374
|
};
|
365
375
|
|
376
|
+
// драг энд дроп и прочая мышь
|
366
377
|
var initAddControls = function () {
|
367
378
|
var map = self.map,
|
368
379
|
mapbody = $('.mmap-image', self.map);
|
@@ -511,6 +522,7 @@ var clog = function () {
|
|
511
522
|
if (p.obj && p.obj.building) {
|
512
523
|
var building = p.obj.building;
|
513
524
|
clog("<mouseup> Входим в здание.");
|
525
|
+
self.current_building = building;
|
514
526
|
building.enter();
|
515
527
|
}
|
516
528
|
|
@@ -829,7 +841,7 @@ var clog = function () {
|
|
829
841
|
*
|
830
842
|
*/
|
831
843
|
self.draw_map_object_image_bg = function (img_src, params) {
|
832
|
-
console.log('<draw_map_object_image_bg>');
|
844
|
+
//console.log('<draw_map_object_image_bg>');
|
833
845
|
|
834
846
|
// породим DOM
|
835
847
|
var $div_map_object_image_bg = $('<div></div>')
|
@@ -859,6 +871,10 @@ var clog = function () {
|
|
859
871
|
|
860
872
|
};
|
861
873
|
|
874
|
+
self.clear_all_map_object_image_bg = function () {
|
875
|
+
$('.map_object_image_bg').parent().remove();
|
876
|
+
};
|
877
|
+
|
862
878
|
/**
|
863
879
|
* Задача этой служебной функции:
|
864
880
|
* - рассчёт актуальных (для данного масштаба) размеров и координат местонах указанного объекта (вместо объекта подаётся хэш описывающий его, с x,y,width,height)
|
@@ -891,7 +907,7 @@ var clog = function () {
|
|
891
907
|
style += "height:";
|
892
908
|
style += height + 'px;';
|
893
909
|
|
894
|
-
console.log("> scale: " + self.scale + "; style: " + style);
|
910
|
+
//console.log("> scale: " + self.scale + "; style: " + style);
|
895
911
|
$i.attr('style',style);
|
896
912
|
|
897
913
|
};
|
@@ -1102,7 +1118,7 @@ var clog = function () {
|
|
1102
1118
|
* @private
|
1103
1119
|
*/
|
1104
1120
|
var __moveToComplete = function (x,y,scale) {
|
1105
|
-
console.log("<__moveToComplete> x = " + x + "; y = " + y + "; scale = " + scale);
|
1121
|
+
//console.log("<__moveToComplete> x = " + x + "; y = " + y + "; scale = " + scale);
|
1106
1122
|
|
1107
1123
|
/* NOTE:: CORE */
|
1108
1124
|
|
@@ -1217,8 +1233,8 @@ var clog = function () {
|
|
1217
1233
|
};
|
1218
1234
|
|
1219
1235
|
// показать инфо о здании
|
1220
|
-
self.
|
1221
|
-
console.log("<main.showBuildingInfo> Показать информацию о Rent-здании с id = " + rent_building_hash.id);
|
1236
|
+
self.showBuildingInfo_old = function (rent_building_hash) {
|
1237
|
+
//console.log("<main.showBuildingInfo> Показать информацию о Rent-здании с id = " + rent_building_hash.id);
|
1222
1238
|
|
1223
1239
|
//"rent_building_hash": {
|
1224
1240
|
// "id": 2,
|
@@ -1329,7 +1345,7 @@ var clog = function () {
|
|
1329
1345
|
// извлекаем значения
|
1330
1346
|
var rent_area_id = $s.val();
|
1331
1347
|
var map_area_id = self.current_area.id;
|
1332
|
-
console.log("<Map.link_area> rent_area_id = " + rent_area_id + "; map_area_id = " + map_area_id);
|
1348
|
+
//console.log("<Map.link_area> rent_area_id = " + rent_area_id + "; map_area_id = " + map_area_id);
|
1333
1349
|
|
1334
1350
|
// нажимаем кнопку "закрыть"
|
1335
1351
|
$b.click();
|
@@ -1357,7 +1373,7 @@ var clog = function () {
|
|
1357
1373
|
// взять C80MapFloors::current_building и назначить ему Rent::building.id,
|
1358
1374
|
// выбранный в окне _modal_window.html.erb
|
1359
1375
|
self.link_building = function () {
|
1360
|
-
console.log('<Map.link_building> ');
|
1376
|
+
//console.log('<Map.link_building> ');
|
1361
1377
|
|
1362
1378
|
// фиксируем компоненты модального окна
|
1363
1379
|
var $m = $('#modal_window');
|
@@ -1367,7 +1383,7 @@ var clog = function () {
|
|
1367
1383
|
// извлекаем значения
|
1368
1384
|
var rent_building_id = $s.val();
|
1369
1385
|
var map_building_id = self.current_building.id;
|
1370
|
-
console.log("<Map.link_area> rent_building_id = " + rent_building_id + "; map_building_id = " + map_building_id);
|
1386
|
+
//console.log("<Map.link_area> rent_building_id = " + rent_building_id + "; map_building_id = " + map_building_id);
|
1371
1387
|
|
1372
1388
|
// нажимаем кнопку "закрыть"
|
1373
1389
|
$b.click();
|
@@ -139,7 +139,7 @@ function StateController() {
|
|
139
139
|
if (_this.building_info.data("init") == undefined) {
|
140
140
|
_this.building_info.data('init', _this.building_info.css("top"));
|
141
141
|
}
|
142
|
-
_this.building_info.css("top", -
|
142
|
+
_this.building_info.css("top", -400);
|
143
143
|
_this.building_info.css("display", "block");
|
144
144
|
|
145
145
|
// скроем кнопку "забронировать площадь"
|
@@ -2,7 +2,7 @@ var MapUtils = {
|
|
2
2
|
|
3
3
|
svgOverlayHideAllExcept: function ($g) {
|
4
4
|
if ($g != null) {
|
5
|
-
console.log("<MapUtils.svgOverlayHideAllExcept>");
|
5
|
+
//console.log("<MapUtils.svgOverlayHideAllExcept>");
|
6
6
|
|
7
7
|
// убираем у всех g из svg_overlay класс viewing_area
|
8
8
|
$g.parent().find('g').css('display','none');
|
@@ -15,7 +15,7 @@ var MapUtils = {
|
|
15
15
|
|
16
16
|
svgOverlayRestore: function ($g) {
|
17
17
|
if ($g != null) {
|
18
|
-
console.log("<MapUtils.svgOverlayRestore>");
|
18
|
+
//console.log("<MapUtils.svgOverlayRestore>");
|
19
19
|
$g.parent().find('g').css('display','block');
|
20
20
|
}
|
21
21
|
}
|
@@ -0,0 +1,191 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
// Знает о том, что где-то на странице живет контейнер .tabs_js
|
4
|
+
// <div class="tabs_js">
|
5
|
+
// <div class="tab_buttons clearfix"></div>
|
6
|
+
// <div class="tab_content clearfix"></div>
|
7
|
+
// </div>
|
8
|
+
//
|
9
|
+
// NOTE-q:: невнятно подвешен вопрос касательно количества подобных компонентов на странице
|
10
|
+
// NOTE-q:: код написан с условием, что на странице живет один tabs_js, сейчас пока нет времени думать о нём
|
11
|
+
//
|
12
|
+
|
13
|
+
function Tabs(options) {
|
14
|
+
|
15
|
+
var _this = this;
|
16
|
+
|
17
|
+
// параметры, по которым построен компонент
|
18
|
+
var _options;
|
19
|
+
|
20
|
+
// view контейнеры, в которых живут кнопки и контент
|
21
|
+
var _$div_tabs;
|
22
|
+
var _$div_tab_buttons;
|
23
|
+
var _$div_tab_content;
|
24
|
+
|
25
|
+
// массив кнопок
|
26
|
+
var _tab_buttons = [];
|
27
|
+
|
28
|
+
// массив содержимого вкладок
|
29
|
+
var _tab_contents = [];
|
30
|
+
|
31
|
+
// айди текущей просматриваемой вкладки
|
32
|
+
var _current_tab_id = -1;
|
33
|
+
|
34
|
+
// zero-based индекс текущей просматриваемой вкладки
|
35
|
+
var _selected_index = -1;
|
36
|
+
|
37
|
+
// структура данных, которая описывает текущее содержимое копонента: кнопки и контент
|
38
|
+
var _data = {};
|
39
|
+
|
40
|
+
// хэш колбеков: при клике по кнопке с id=ID будет вызван соответствующий колбэк
|
41
|
+
var _callbacks = {};
|
42
|
+
|
43
|
+
//--[ public ]----------------------------------------------------------------------------------------------------------------------
|
44
|
+
|
45
|
+
/**
|
46
|
+
* Удалить все элементы: кнопки, вкладки и данные
|
47
|
+
*/
|
48
|
+
this.removeAll = function () {
|
49
|
+
console.log('<removeAll>');
|
50
|
+
|
51
|
+
// очистим данные
|
52
|
+
_data = {};
|
53
|
+
|
54
|
+
// очистим массив колбэков
|
55
|
+
_callbacks = {};
|
56
|
+
|
57
|
+
// сбросим курсор
|
58
|
+
_current_tab_id = -1;
|
59
|
+
|
60
|
+
// удалим все кнопки и слушатели
|
61
|
+
for (var i = 0; i < _tab_buttons.length; i++) {
|
62
|
+
var $ibuttn = _tab_buttons[i];
|
63
|
+
$ibuttn.remove();
|
64
|
+
$ibuttn.off('click', this._onTabButtonClick)
|
65
|
+
}
|
66
|
+
|
67
|
+
};
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Добавить именованную вкладку.
|
71
|
+
*
|
72
|
+
*
|
73
|
+
* @param tab_title
|
74
|
+
* @param tab_id
|
75
|
+
* @param on_tab_show
|
76
|
+
*
|
77
|
+
*/
|
78
|
+
this.addTab = function (tab_title, tab_id, on_tab_show) {
|
79
|
+
|
80
|
+
// создадим кнопку и контент
|
81
|
+
var btn = this._buttonAdd(tab_title, tab_id, on_tab_show);
|
82
|
+
//var cnt = this._contentAdd();
|
83
|
+
|
84
|
+
// запишем это в структуру
|
85
|
+
_data[tab_id] = {
|
86
|
+
tab_button: btn,
|
87
|
+
tab_content: null
|
88
|
+
};
|
89
|
+
|
90
|
+
// поместим в массивы
|
91
|
+
//_tab_contents.push(cnt);
|
92
|
+
|
93
|
+
};
|
94
|
+
|
95
|
+
this.setSelectedIndex = function (index) {
|
96
|
+
console.log('<setSelectedIndex> index: ' + index);
|
97
|
+
_$div_tab_buttons.find('a[data-index='+index+']')
|
98
|
+
.click();
|
99
|
+
};
|
100
|
+
|
101
|
+
//--[ controller ]----------------------------------------------------------------------------------------------------------------------
|
102
|
+
|
103
|
+
this._onTabButtonClick = function (e) {
|
104
|
+
//console.log('<_onTabButtonClick>');
|
105
|
+
//console.log(e);
|
106
|
+
e.preventDefault();
|
107
|
+
|
108
|
+
// фиксируем кнопку
|
109
|
+
var $clicked_button = $(e.target);
|
110
|
+
|
111
|
+
// зафиксируем id нажатой кнопки
|
112
|
+
var clicked_id = $clicked_button.data('id');
|
113
|
+
//console.log('<_onTabButtonClick> clicked_id: ' + clicked_id);
|
114
|
+
|
115
|
+
// зафиксируем index нажатой кнопки
|
116
|
+
var clicked_index = $clicked_button.data('index');
|
117
|
+
//console.log('<_onTabButtonClick> clicked_index: ' + clicked_index);
|
118
|
+
|
119
|
+
// сравним с курсором, колбэк вызовем, только если есть изменения
|
120
|
+
if (_current_tab_id != clicked_id) {
|
121
|
+
|
122
|
+
_current_tab_id = clicked_id;
|
123
|
+
_selected_index = clicked_index;
|
124
|
+
|
125
|
+
var fun = _callbacks[clicked_id];
|
126
|
+
if (fun != undefined) {
|
127
|
+
fun(clicked_id);
|
128
|
+
}
|
129
|
+
|
130
|
+
}
|
131
|
+
|
132
|
+
// сделаем эту кнопку активной
|
133
|
+
_$div_tab_buttons
|
134
|
+
.find('a')
|
135
|
+
.removeClass('active');
|
136
|
+
_$div_tab_buttons
|
137
|
+
.find('a[data-index='+clicked_index+']')
|
138
|
+
.addClass('active');
|
139
|
+
|
140
|
+
};
|
141
|
+
|
142
|
+
//--[ private ]----------------------------------------------------------------------------------------------------------------------
|
143
|
+
|
144
|
+
this._buttonAdd = function (tab_button_title, button_id, on_click_callback) {
|
145
|
+
console.log('<_addTabButton> tab_button_title: ' + tab_button_title);
|
146
|
+
|
147
|
+
// создадим кнопку
|
148
|
+
var b = $('<a href="#"></a>')
|
149
|
+
.text(tab_button_title)
|
150
|
+
.attr('data-id',button_id)
|
151
|
+
.attr('data-index', _tab_buttons.length)
|
152
|
+
//.data('id', button_id)
|
153
|
+
//.data('index', _tab_buttons.length)
|
154
|
+
.appendTo(_$div_tab_buttons)
|
155
|
+
.on('click', this._onTabButtonClick);
|
156
|
+
|
157
|
+
// её колбэк поместим в отдельный массив
|
158
|
+
_callbacks[button_id] = on_click_callback;
|
159
|
+
|
160
|
+
_tab_buttons.push(b);
|
161
|
+
|
162
|
+
};
|
163
|
+
|
164
|
+
this._contentAdd = function () {
|
165
|
+
|
166
|
+
};
|
167
|
+
|
168
|
+
this._buttonRemove = function ($a_button) {
|
169
|
+
|
170
|
+
};
|
171
|
+
|
172
|
+
this._contentRemove = function () {
|
173
|
+
|
174
|
+
};
|
175
|
+
|
176
|
+
this._fInit = function (options) {
|
177
|
+
|
178
|
+
// найдем нужную DOM структуру
|
179
|
+
_$div_tabs = $('.tabs_js');
|
180
|
+
if (_$div_tabs.length) { /*NOTE-q*/
|
181
|
+
_$div_tab_buttons = _$div_tabs.find('.tab_buttons');
|
182
|
+
_$div_tab_content = _$div_tabs.find('.tab_content');
|
183
|
+
}
|
184
|
+
|
185
|
+
};
|
186
|
+
|
187
|
+
//--[ startup ]----------------------------------------------------------------------------------------------------------------------
|
188
|
+
|
189
|
+
this._fInit(options);
|
190
|
+
|
191
|
+
}
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
// содержит компонент Tabs, пользуется им для отображения информации об этажах здания
|
4
|
+
|
5
|
+
function BuildingInfo(options) {
|
6
|
+
|
7
|
+
// текуще отображаемое здание
|
8
|
+
var _cur_map_building_json;
|
9
|
+
|
10
|
+
// настраиваемые параметры
|
11
|
+
var _options = {
|
12
|
+
onFloorTabChange: undefined
|
13
|
+
};
|
14
|
+
|
15
|
+
// заголовок - название здания
|
16
|
+
var _$title;
|
17
|
+
|
18
|
+
// компонент "вкладки"
|
19
|
+
var _tabs = null;
|
20
|
+
|
21
|
+
// привязка данных об этажах здания ко вкладкам в этом удобном хэше
|
22
|
+
var _tabs_floors_data = {};
|
23
|
+
|
24
|
+
//-[ public ]-----------------------------------------------------------------------------------------------------------------------
|
25
|
+
|
26
|
+
/** Получить данные для отображения.
|
27
|
+
*
|
28
|
+
* @param map_building_json Это данные от C80MapFloors::MapBuilding
|
29
|
+
*/
|
30
|
+
this.setData = function (map_building_json) {
|
31
|
+
//console.log('<BuildingInfo.setData>');
|
32
|
+
//console.log(map_building_json);
|
33
|
+
|
34
|
+
_cur_map_building_json = map_building_json;
|
35
|
+
|
36
|
+
this._removeAll();
|
37
|
+
this._parseData();
|
38
|
+
this._updateView();
|
39
|
+
|
40
|
+
};
|
41
|
+
|
42
|
+
/**
|
43
|
+
* П
|
44
|
+
* @param floor_index
|
45
|
+
*/
|
46
|
+
this.setSelectedFloor = function (floor_index) {
|
47
|
+
_tabs.setSelectedIndex(floor_index);
|
48
|
+
};
|
49
|
+
|
50
|
+
//------------------------------------------------------------------------------------------------------------------------
|
51
|
+
|
52
|
+
/**
|
53
|
+
* слушает клики по табам, отправляет команды выше.
|
54
|
+
*
|
55
|
+
* @param shown_tab_id - айди текуще отображённой вкладки, это floor id NOTE:fidfid
|
56
|
+
* @private
|
57
|
+
*/
|
58
|
+
this._onTabShow = function (shown_tab_id) {
|
59
|
+
console.log('<_onTabShow> shown_tab_id = ' + shown_tab_id);
|
60
|
+
|
61
|
+
if (_options['onFloorTabChange'] != undefined) {
|
62
|
+
_options['onFloorTabChange'](shown_tab_id);
|
63
|
+
}
|
64
|
+
};
|
65
|
+
|
66
|
+
//---[ dsd ]---------------------------------------------------------------------------------------------------------------------
|
67
|
+
|
68
|
+
this._fInit = function (options) {
|
69
|
+
// TODO:: _options extend options
|
70
|
+
_options = $.extend(_options, options);
|
71
|
+
|
72
|
+
// создаём компонент "вкладки"
|
73
|
+
_tabs = new Tabs();
|
74
|
+
|
75
|
+
// находим заголовок
|
76
|
+
_$title = $('.building_info').find('h3');
|
77
|
+
|
78
|
+
};
|
79
|
+
|
80
|
+
this._parseData = function () {
|
81
|
+
console.log('<BuildingInfo._parseData>');
|
82
|
+
|
83
|
+
// установим заголовок окна
|
84
|
+
_$title.text(_cur_map_building_json["title"]);
|
85
|
+
|
86
|
+
// обойдём этажи, построим вкладки
|
87
|
+
for (var i = 0; i < _cur_map_building_json['floors'].length; i++) {
|
88
|
+
|
89
|
+
var ifloor_data = _cur_map_building_json['floors'][i];
|
90
|
+
var ifloor_id = ifloor_data["id"]; // NOTE:fidfid
|
91
|
+
//console.log(ifloor_data); // => see C80MapFloors::Floor.as_json
|
92
|
+
|
93
|
+
// создадим вкладку
|
94
|
+
_tabs.addTab(ifloor_data["title"], ifloor_id, this._onTabShow);
|
95
|
+
|
96
|
+
// свяжем её по id с даными
|
97
|
+
_tabs_floors_data[ifloor_id] = {
|
98
|
+
tab_data: ifloor_data
|
99
|
+
}
|
100
|
+
}
|
101
|
+
};
|
102
|
+
|
103
|
+
this._updateView = function () {
|
104
|
+
|
105
|
+
};
|
106
|
+
|
107
|
+
// очистим данные и вью
|
108
|
+
this._removeAll = function () {
|
109
|
+
|
110
|
+
_$title.text('');
|
111
|
+
_tabs_floors_data = {};
|
112
|
+
_tabs.removeAll();
|
113
|
+
};
|
114
|
+
|
115
|
+
|
116
|
+
this._fInit(options);
|
117
|
+
}
|
@@ -8,7 +8,7 @@ module C80MapFloors
|
|
8
8
|
acts_as_base_map_object
|
9
9
|
|
10
10
|
# validates :coords, uniqueness: true
|
11
|
-
|
11
|
+
after_save :update_json
|
12
12
|
|
13
13
|
mount_uploader :img_bg, C80MapFloors::FloorImageUploader # TODO:: FloorImageUploader класс должен использоваться только для загрузки img_bg [потому что 78aasq]
|
14
14
|
mount_uploader :img_overlay, C80MapFloors::FloorImageUploader
|
@@ -16,18 +16,27 @@ module C80MapFloors
|
|
16
16
|
# NOTE:: Т.к. для этажей используются картинки в два раза детальнее (в два раза больше, чем оригинал карты), то делим попалам
|
17
17
|
# размеры картинки уйдут в js - они помогут её css-абсолютно правильно масштабировать и позиционировать
|
18
18
|
def img_bg_width
|
19
|
-
|
20
|
-
|
19
|
+
res = nil
|
20
|
+
if img_bg.present?
|
21
|
+
img = MiniMagick::Image.open(img_bg.path)
|
22
|
+
res = img["width"]/2
|
23
|
+
end
|
24
|
+
res
|
21
25
|
end
|
22
26
|
|
23
27
|
def img_bg_height
|
24
|
-
|
25
|
-
|
28
|
+
res = nil
|
29
|
+
if img_bg.present?
|
30
|
+
img = MiniMagick::Image.open(img_bg.path)
|
31
|
+
res = img["height"]/2
|
32
|
+
end
|
33
|
+
res
|
26
34
|
end
|
27
35
|
|
28
36
|
# private
|
29
37
|
|
30
38
|
# TODO:: после того, как апдейтим этаж, не обновляются данные в JSON - изза ебучей ошибки с путями в CarrierWave
|
39
|
+
# Т.е. нужно руками, после того, как в базу лягут актуальные данные, вызвать save! какого-нибудь building
|
31
40
|
def update_json
|
32
41
|
Rails.logger.debug "[TRACE] <update_json> nope"
|
33
42
|
# MapJson.update_json
|
@@ -1,17 +1,7 @@
|
|
1
1
|
<div class="building_info">
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
<li id="gate_type">Тип ворот: <span></span></li>
|
9
|
-
<li id="communications">Коммуникации: <span></span></li>
|
10
|
-
</ul>
|
11
|
-
<h5 id="price"><span></span></h5>
|
12
|
-
<%= link_to "Оставить заявку",
|
13
|
-
"#",
|
14
|
-
:class => 'ebutton c80_order_invoking_btn',
|
15
|
-
:data => { :comment_text => "этот будет заменён ajax Ответом, заполняющим инфо о площади", :subj_id => 'Это число будет подставлено ajax Ответом' },
|
16
|
-
:id => 'area_order_button' %>
|
17
|
-
</div>
|
2
|
+
<h3 class="title"></h3>
|
3
|
+
<div class="tabs_js">
|
4
|
+
<div class="tab_buttons clearfix"></div>
|
5
|
+
<div class="tab_content clearfix"></div>
|
6
|
+
</div>
|
7
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class="building_info">
|
2
|
+
<h2></h2>
|
3
|
+
<ul> <%# idишники элементов списка - имена полей таблицы Rent::Building %>
|
4
|
+
<li id="square">Общая площадь: <span></span> м кв.</li>
|
5
|
+
<li id="free_square">Свободная площадь: <span></span> м кв.</li>
|
6
|
+
<li id="floor_height">Высота потолка: <span></span></li>
|
7
|
+
<li id="column_step">Шаг колонн: <span></span></li>
|
8
|
+
<li id="gate_type">Тип ворот: <span></span></li>
|
9
|
+
<li id="communications">Коммуникации: <span></span></li>
|
10
|
+
</ul>
|
11
|
+
<h5 id="price"><span></span></h5>
|
12
|
+
<%= link_to "Оставить заявку",
|
13
|
+
"#",
|
14
|
+
:class => 'ebutton c80_order_invoking_btn',
|
15
|
+
:data => { :comment_text => "этот будет заменён ajax Ответом, заполняющим инфо о площади", :subj_id => 'Это число будет подставлено ajax Ответом' },
|
16
|
+
:id => 'area_order_button' %>
|
17
|
+
</div>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: c80_map_floors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.0.
|
4
|
+
version: 0.1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- C80609A
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-10-
|
11
|
+
date: 2016-10-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -137,6 +137,8 @@ files:
|
|
137
137
|
- app/assets/javascripts/svg_elements/building_label.js
|
138
138
|
- app/assets/javascripts/svg_elements/helper.js
|
139
139
|
- app/assets/javascripts/svg_elements/polygon.js
|
140
|
+
- app/assets/javascripts/ui/tabs/tabs.js
|
141
|
+
- app/assets/javascripts/view/building_info/building_info.js
|
140
142
|
- app/assets/javascripts/view/save_preloader.js
|
141
143
|
- app/assets/stylesheets/c80_map_floors.scss
|
142
144
|
- app/assets/stylesheets/map.scss
|
@@ -175,6 +177,7 @@ files:
|
|
175
177
|
- app/views/c80_map_floors/shared/_save_preloader.html.erb
|
176
178
|
- app/views/c80_map_floors/shared/map_row/_area_order_button.html.erb
|
177
179
|
- app/views/c80_map_floors/shared/map_row/_building_info.html.erb
|
180
|
+
- app/views/c80_map_floors/shared/map_row/_building_info_old.html.erb
|
178
181
|
- bin/console
|
179
182
|
- bin/setup
|
180
183
|
- c80_map_floors.gemspec
|