{% extends 'grid.html.twig' %}
{% block mainContainer %}
{# {{ form(form) }}#}
<div id="map_form"></div>
<img src="{{ asset('/static/preloader.gif') }}" id="preloader" style="display: none;" />
<div id="map"
data-city-uri-idenity="{{ cityUriIdentity }}"
data-city-latitude="{{ cityLatitude }}"
data-city-longitude="{{ cityLongitude }}"
style="width:100%; height:500px;"></div>
{% endblock %}
{% block javascripts %}
<script src="{{ asset('bundles/fosjsrouting/js/router.min.js') }}"></script>
<script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
<script type="text/javascript">
;var RoutingDecorator = {
generate: function (name, params) {
const orig_name = name;
try {
Routing.getRoute(name)
} catch(error) {
name = name + '.' + '{{ app.request.locale }}';
try {
Routing.getRoute(name)
} catch(error) {
name = orig_name;
}
}
return Routing.generate(name, params);
}
};
;(function () {
document.addEventListener('DOMContentLoaded', _ => {
var avatarPath = '{{ asset('', 'profile_media_avatar') }}';
var photoPath = '{{ asset('', 'profile_media') }}';
var thumbPath = '{{ asset('', 'saloon_media_thumb') }}';
var mapContainer = document.querySelector('#map');
var preloader = document.querySelector('#preloader');
var cityUriIdentity = mapContainer.getAttribute('data-city-uri-idenity');
var cityLatitude = mapContainer.getAttribute('data-city-latitude');
var cityLongitude = mapContainer.getAttribute('data-city-longitude');
var formName = 'filter_map_form';
var multipleCities = {{ multipleCities }};
var routesUrl = '/js/fos_js_routes{{ multipleCities ? '_city_prefixed' }}.json';
loadRoutes();
var myMap, clusterer;
ymaps.ready(function () {
myMap = new ymaps.Map('map', {
center: [cityLatitude, cityLongitude],
zoom: 9,
behaviors: ['default', 'scrollZoom']
}, {
searchControlProvider: 'yandex#search'
});
clusterer = new ymaps.Clusterer({
preset: 'islands#invertedVioletClusterIcons',//Через кластеризатор можно указать только стили кластеров,стили для меток нужно назначать каждой метке отдельно.
groupByCoordinates: false,//Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
//Опции кластеров указываем в кластеризаторе с префиксом "cluster".
clusterDisableClickZoom: true,
clusterHideIconOnBalloonOpen: false,
geoObjectHideIconOnBalloonOpen: false
});
// Можно менять опции кластеризатора после создания.
clusterer.options.set({
gridSize: 80,
clusterDisableClickZoom: true
});
loadForm();
});
function loadRoutes() {
$.ajax({
url:routesUrl,
dataType: "json",
async: false,
success: function (routes) {
Routing.setRoutingData(routes);
},
error: function (xhr, ajaxOptions, thrownError) {}
});
}
function setFormSubmitListener() {
document.querySelector("form[name="+formName+"]").addEventListener('submit', function(e){
e.preventDefault();
if(!clusterer)
return;
filterData();
return false;
});
}
function loadForm() {
fetch('{{ path('map.form', {city: cityUriIdentity}) }}', {
mode: "cors",
importance: "low",
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"X-Requested-With": "XMLHttpRequest"
},
}).then(response => {
if (response.status < 300) {
return response.text();
} else {
console.warn("🤔");
return null;
}
}).then(response => {
document.querySelector('#map_form').innerHTML = response;
filterData();
setFormSubmitListener();
});
}
function filterData() {
preloader.style.display = 'block';
var data = {};
$("form[name="+formName+"]").serializeArray().forEach((object)=>{
//"подгоняем" данные под формат, ожидаемый формой при сабмите
var fieldName = object.name.toString().replace(formName + '[', '').replace(']', '');
var clearFieldName = fieldName.substr(0, fieldName.indexOf('['));
if(~fieldName.indexOf('[]')) {
checkArrayIsInFormObject(clearFieldName, data);
data[clearFieldName].push(object.value);
} else if(~fieldName.indexOf('[m')) {
if(!object.value)
return;
checkObjectIsInFormObject(clearFieldName, data);
if(~fieldName.indexOf('[min]'))
data[clearFieldName]['min'] = object.value;
if(~fieldName.indexOf('[max]'))
data[clearFieldName]['max'] = object.value;
} else {
data[fieldName] = object.value;
}
});
$.ajax({
url:'{{ path('map.filter', {city:cityUriIdentity}) }}',
type: "POST",
dataType: "json",
data: {
"form": JSON.stringify(data),
},
async: true,
success: function (return_data) {
// console.log(return_data);
updateMap(return_data);
preloader.style.display = 'none';
},
error: function (xhr, ajaxOptions, thrownError) {}
});
}
function checkArrayIsInFormObject(name, formObject) {
if(false == formObject.hasOwnProperty(name))
formObject[name] = [];
}
function checkObjectIsInFormObject(name, formObject) {
if(false == formObject.hasOwnProperty(name))
formObject[name] = {};
}
function updateMap(points) {
clusterer.removeAll();
if(!points || !points.length)
return;
var getImgUrl = function(path, imgType) {
if(path[0] == '/')
return path;
var assetPackagePath = '';
if(imgType == 'avatar')
assetPackagePath = avatarPath;
else if(imgType == 'photo')
assetPackagePath = photoPath;
if(imgType == 'thumb')
assetPackagePath = thumbPath;
return assetPackagePath + path;
};
var getPointData = function (index) {
const data = points[index];
const isProfile = data[0] == 1;
const isSaloon = data[0] == 2;
let url = '';
const uri = data[3];
if(isProfile) {
url = RoutingDecorator.generate(
'profile_preview.page',
multipleCities ? {city: cityUriIdentity, profile: uri} : {profile: uri}
);
} else if(isSaloon) {
url = RoutingDecorator.generate(
'saloon_preview.page',
multipleCities ? {city: cityUriIdentity, saloon: uri} : {saloon: uri}
);
}
var processProfileShowsUrl = '{{ path('map.increment_profile_shows', multipleCities ? {city:cityUriIdentity} : {}) }}';
return {
balloonContentHeader: '',
balloonContentBody: '<p><img src="' + getImgUrl(data[5], isProfile ? 'avatar' : 'thumb') + '" width="100" /></p>' + '<font size=3><b><a target="_blank" href="' + url + '">Профиль</a></b></font>'
+ '<img style="display:none;" width="0" height="0" src="' + processProfileShowsUrl + '?id=' + (isProfile ? data[9] : null)+'" />', //не убирать, функционально важно
balloonContentFooter: '<font size=1>' + data[8] + ',' + data[9] + ',' + data[10] + '</strong>',
clusterCaption: '<strong>' + (isSaloon ? 'Салон ' : '') + data[4] + '</strong>'
};
};
var getPointOptions = function (index, type) {
return {
preset: type == 'profile' ? 'islands#violetIcon' : 'islands#redIcon'
};
};
var geoObjects = [];
for(var i = 0, len = points.length; i < len; i++)
geoObjects[i] = new ymaps.Placemark([points[i][1], points[i][2]], getPointData(i), getPointOptions(i, points[i][0] == 1));
//В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
clusterer.add(geoObjects);
myMap.geoObjects.add(clusterer);
// Спозиционируем карту так, чтобы на ней были видны все объекты.
myMap.setBounds(clusterer.getBounds(), {
checkZoomRange: true
});
}
});
})();
</script>
{% endblock %}