PageSourceSearch

https://vl-k.su/bitrix/js/citrus.core/citrus/map/jquery.citrusObjectsMap.js?16569247238855

js vl-k.su collected 2026-10-07 13:16:01 UTC 8,855 bytes, 294 lines download raw bytes

1"use strict";
2
3/**
4 * Êëàññ äëÿ ãåîêîäèðîâàíèÿ ñïèñêà àäðåñîâ èëè êîîðäèíàò.
5 * @class
6 * @name MultiGeocoder
7 * @param {Object} [options={}] Äåôîëòíûå îïöèè ìóëüòèãåîêîäåðà.
8 */
9function MultiGeocoder(options) {
10	this._options = options || {results: 1};
11}
12
13/**
14 * Ôóíêöèÿ ìíîæåñòâåííåîãî ãåîêîäèðîâàíèÿ.
15 * @function
16 * @requires ymaps.util.extend
17 * @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/util.extend.xml
18 * @requires ymaps.util.Promise
19 * @see http://api.yandex.ru/maps/doc/jsapi/2.x/ref/reference/util.Promise.xml
20 * @name MultiGeocoder.geocode
21 * @param {Array} requests Ìàññèâ ñòðîê-èìåí òîïîíèìîâ è/èëè ãåîìåòðèé òî÷åê (îáðàòíîå ãåîêîäèðîâàíèå)
22 * @returns {Object} Êàê è â îáû÷íîì ãåîêîäåðå, âåðíåì îáúåêò-îáåùàíèå.
23 */
24MultiGeocoder.prototype.geocode = function (requests, options) {
25	var self = this,
26		size = requests.length,
27		geoObjects = new ymaps.GeoObjectCollection({}),
28		promise = new ymaps.vow.Promise(function (resolve, reject) {
29
30			requests.forEach(function (request, index) {
31				ymaps.geocode(request, ymaps.util.extend({}, self._options, options))
32				.then(
33					function (response) {
34						var geoObject = response.geoObjects.get(0);
35						if (!geoObject) {
36							--size || resolve({geoObjects: geoObjects});
37							return;
38						}
39						geoObject._idx = index;
40
41						geoObject && geoObjects.add(geoObject);
42						--size || resolve({geoObjects: geoObjects});
43					},
44					function (err) {
45						console.error(err);
46						reject(err);
47					}
48				);
49			});
50
51		});
52
53	return promise;
54};
55
56(function ($) {
57
58	$.fn.citrusObjectsMap = function (options) {
59		var self = this;
60		self.options = $.extend({}, $.fn.citrusObjectsMap.defaults, options);
61		self.$map = $('#' + self.options.id);
62
63		if (self.options.height) self.$map.height(self.options.height);
64
65		var updateGeoObjectCurrency = function (o) {
66			if (typeof currency === 'undefined') return;
67			var $baloonBody = $('<div>'+o.properties.get('balloonContentBody')+'</div>');
68			currency.updateHtml($baloonBody);
69			o.properties.set('balloonContentBody', $baloonBody[0].outerHTML);
70		};
71
72		this.createMap = function (objects) {
73
74			var countObjects = objects.length,
75				mapOptions = {
76					controls: self.options.controls,
77				};
78			if (!countObjects) {
79				// no items found — hide map container
80				self.options.onEmptyObject.call(this);
81				return;
82			}
83
84			if (countObjects === 1) {
85				mapOptions.center = objects[0].geometry.getCoordinates();
86				mapOptions.zoom = 16;
87			} else {
88				var points = [];
89				objects.forEach(function (o) {
90					points.push(o.geometry.getCoordinates());
91				});
92				mapOptions.bounds = ymaps.util.bounds.fromPoints(points);
93				mapOptions.margin = 50;
94			}
95			self.yamap = new ymaps.Map(self.options.id, mapOptions, {
96				avoidFractionalZoom: false
97			});
98
99			// todo ïðîâåðèòü ðàáîòó zoomRange
100			{
101				var zoom = self.yamap.getZoom();
102				var zoomRange = self.yamap.zoomRange.getCurrent();
103				if (zoom < zoomRange[0]) self.yamap.setZoom(zoomRange[0]);
104				if (zoom > 16) self.yamap.setZoom(16);
105				if (zoom > zoomRange[1]) self.yamap.setZoom(zoomRange[1]);
106			}
107
108			if (self.options.touchScroll && BX.browser.DetectIeVersion() < 0) {
109				ymapsTouchScroll(self.yamap, {
110					textScroll: BX.message('YAMAP_TOUCH_SCROLL__TEXT_SCROLL'),
111					textTouch: BX.message('YAMAP_TOUCH_SCROLL__TEXT_TOUCH')
112				});
113			}
114
115            if (!self.options.canSelect) {
116
117			self.yamap.events.add('click', function (e) {
118				var map = e.get('target');
119				map.balloon && map.balloon.isOpen() ? map.balloon.close() : false;
120			});
121
122            } else {
123                self.yamap.events.add('click', function (e) {
124                    var coords = e.get('coords');
125                    if (self.placemark) {
126                        self.placemark.geometry.setCoordinates(coords);
127                        self.options.onSelectCoords.call(this, coords);
128                    }
129                });
130            }
131
132			if (countObjects > 1) {
133				/**
134				 * @var {string} citrusTemplateColor - êîä öâåòà èêîíêè, ïî óìîë÷àíèþ '#1e98ff'
135				 */
136
137				var clusterer = new ymaps.Clusterer({
138					// preset: 'islands#' + self.options.theme + 'ClusterIcons',
139					clusterIconColor: (typeof citrusTemplateColor !== 'undefined') ? citrusTemplateColor : '#1e98ff',
140					margin: 50,
141					clusterDisableClickZoom: false,
142
143					clusterBalloonContentLayout: 'cluster#balloonCarousel',
144					clusterBalloonPagerType: 'marker',
145					clusterBalloonContentLayoutHeight: 360,
146					clusterBalloonContentLayoutWidth: 205
147				});
148				clusterer.add(objects);
149
150				clusterer.events.add('balloonopen', function (e) {
151					var clusterPlacemark = e.get('cluster');
152					if (typeof clusterPlacemark === 'undefined') return;
153
154					var objects = clusterPlacemark.getGeoObjects();
155					if (objects.length) {
156						objects.forEach(function (o) {
157							updateGeoObjectCurrency(o);
158						});
159					}
160				});
161
162				/* clusterer.events.once('optionschange', function () {
163					 map.setBounds(clusterer.getBounds(), {
164							 checkZoomRange: true,
165							 useMapMargin: true
166						 }
167					 ).then(function() {
168						 if (map.getZoom() > 15)
169							 map.setZoom(15);
170					 });
171				 });*/
172				self.yamap.geoObjects.add(clusterer);
173			} else {
174				self.yamap.geoObjects.add(objects[0]);
175			}
176
177			if ('undefined' !== typeof($().citrusRealtyOfficeMapCheckHash)) {
178				window.setTimeout($().citrusRealtyOfficeMapCheckHash, 500);
179			}
180
181			BX.addCustomEvent('SCHEME', function () {
182				if (typeof clusterer !== 'undefined') clusterer.options.set('clusterIconColor', citrusTemplateColor);
183				objects.forEach(function (o) {
184					o.options.set('iconImageHref', citrusMapIcon.href);
185				});
186			});
187
188			self.options.onReady.call(self);
189		};
190
191		this.initObject = function (geoObject, info) {
192			/**
193			 * @var {object} citrusMapIcon - èêîíêà ÿíäåêñ êàðòû ôîðìàòà { href: 'icon.png', size: [32, 52], offset: [-16, -48]}
194			 * @var {string} citrusMapIconColor - öâåò èêîíêè êàðòû (íàïðèìåð, '#a00' èëè 'red')
195			 */
196			if (typeof citrusMapIcon !== 'undefined' && citrusMapIcon.href && citrusMapIcon.href.length) {
197				geoObject.options.set('iconLayout', 'default#image');
198				geoObject.options.set('iconImageHref', citrusMapIcon.href);
199				geoObject.options.set('iconImageSize', citrusMapIcon.size ? citrusMapIcon.size : [32, 52]);
200				geoObject.options.set('iconImageOffset', citrusMapIcon.offset ? [-16, -48] : citrusMapIcon.offset);
201			} else {
202				geoObject.options.set('preset', info.preset || 'islands#dotIcon');
203				var color = typeof citrusMapIconColor !== 'undefined' ? citrusMapIconColor : '';
204				if (info.color || color) {
205					geoObject.options.set('iconColor', info.color || color);
206				}
207			}
208			geoObject.options.set('balloonCloseButton', false);
209			if (info.header)
210				geoObject.properties.set('balloonContentHeader', info.header);
211			if (info.body)
212				geoObject.properties.set('balloonContentBody', info.body);
213			if (info.footer)
214				geoObject.properties.set('balloonContentFooter', info.footer);
215
216			// update currency
217			geoObject.events.add('balloonopen', function (event) {
218				updateGeoObjectCurrency(geoObject);
219			});
220
221			// global storage for external use
222			geoObject._info = info;
223			if (!('geoObjects' in window)) {
224        window.geoObjects = [];
225      }
226      window.geoObjects.push(geoObject);
227
228			return geoObject;
229		};
230
231		ymaps.ready(function () {
232
233			var geoCoderQueue = [],
234				geoCoderQueueItem = [],
235				objects = [];
236
237			$.each(self.options.items, function (index, item) {
238				if (item.coord) {
239                    var yamapOptions = null;
240                    if (self.options.canSelect) {
241                        yamapOptions = {
242                            hasBalloon: false,
243                        }
244                    }
245					var geoObject = new ymaps.Placemark(item.coord, null, yamapOptions);
246                    objects.push(self.initObject(geoObject, item));
247
248                    if (self.options.canSelect) {
249                        self.placemark = geoObject;
250                    }
251				}
252				else {
253					geoCoderQueue.push(item.address);
254					geoCoderQueueItem.push(item);
255				}
256			});
257
258			if (geoCoderQueue.length) {
259				var geoCoder = new MultiGeocoder({});
260				geoCoder.geocode(geoCoderQueue)
261				.then(function (res) {
262						res.geoObjects.each(function (obj) {
263							objects.push(self.initObject(obj, geoCoderQueueItem[obj._idx]));
264						});
265						self.createMap(objects);
266					},
267					function (err) {
268						self.$map.hide();
269						console.error(err);
270					});
271			} else {
272				self.createMap(objects);
273			}
274		});
275
276		return this;
277	};
278
279	$.fn.citrusObjectsMap.defaults = {
280		id: '',
281		address: '',
282		items: [],
283		controls: ['smallMapDefaultSet'],
284		collapseButton: true,
285		height: 0,
286		onEmptyObject: function () {
287			this.$map.hide();
288		},
289		onReady: function() {},
290        onSelectCoords: function () {},
291		touchScroll: true,
292	};
293
294}(jQuery));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.