templates/Map/page.html.twig line 1

Open in your IDE?
  1. {% extends 'grid.html.twig' %}
  2. {% block mainContainer %}
  3.    {# {{ form(form) }}#}
  4.     <div id="map_form"></div>
  5.     <img src="{{ asset('/static/preloader.gif') }}" id="preloader" style="display: none;" />
  6.     <div id="map"
  7.          data-city-uri-idenity="{{ cityUriIdentity }}"
  8.          data-city-latitude="{{ cityLatitude }}"
  9.          data-city-longitude="{{ cityLongitude }}"
  10.          style="width:100%; height:500px;"></div>
  11. {% endblock %}
  12. {% block javascripts %}
  13.     <script src="{{ asset('bundles/fosjsrouting/js/router.min.js') }}"></script>
  14.     <script src="{{ path('fos_js_routing_js', { callback: 'fos.Router.setData' }) }}"></script>
  15.     <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  16.     <script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>
  17.     <script type="text/javascript">
  18.         ;var RoutingDecorator = {
  19.             generate: function (name, params) {
  20.                 const orig_name = name;
  21.                 try {
  22.                     Routing.getRoute(name)
  23.                 } catch(error) {
  24.                     name = name + '.' + '{{ app.request.locale }}';
  25.                     try {
  26.                         Routing.getRoute(name)
  27.                     } catch(error) {
  28.                         name = orig_name;
  29.                     }
  30.                 }
  31.                 return Routing.generate(name, params);
  32.             }
  33.         };
  34.         ;(function () {
  35.             document.addEventListener('DOMContentLoaded', _ => {
  36.                 var avatarPath = '{{ asset('', 'profile_media_avatar') }}';
  37.                 var photoPath = '{{ asset('', 'profile_media') }}';
  38.                 var thumbPath = '{{ asset('', 'saloon_media_thumb') }}';
  39.                 var mapContainer = document.querySelector('#map');
  40.                 var preloader = document.querySelector('#preloader');
  41.                 var cityUriIdentity = mapContainer.getAttribute('data-city-uri-idenity');
  42.                 var cityLatitude = mapContainer.getAttribute('data-city-latitude');
  43.                 var cityLongitude = mapContainer.getAttribute('data-city-longitude');
  44.                 var formName = 'filter_map_form';
  45.                 var multipleCities = {{ multipleCities }};
  46.                 var routesUrl = '/js/fos_js_routes{{ multipleCities ? '_city_prefixed' }}.json';
  47.                 loadRoutes();
  48.                 var myMap, clusterer;
  49.                 ymaps.ready(function () {
  50.                     myMap = new ymaps.Map('map', {
  51.                             center: [cityLatitude, cityLongitude],
  52.                             zoom: 9,
  53.                             behaviors: ['default', 'scrollZoom']
  54.                         }, {
  55.                             searchControlProvider: 'yandex#search'
  56.                         });
  57.                     clusterer = new ymaps.Clusterer({
  58.                             preset: 'islands#invertedVioletClusterIcons',//Через кластеризатор можно указать только стили кластеров,стили для меток нужно назначать каждой метке отдельно.
  59.                             groupByCoordinates: false,//Ставим true, если хотим кластеризовать только точки с одинаковыми координатами.
  60.                             //Опции кластеров указываем в кластеризаторе с префиксом "cluster".
  61.                             clusterDisableClickZoom: true,
  62.                             clusterHideIconOnBalloonOpen: false,
  63.                             geoObjectHideIconOnBalloonOpen: false
  64.                     });
  65.                     // Можно менять опции кластеризатора после создания.
  66.                     clusterer.options.set({
  67.                         gridSize: 80,
  68.                         clusterDisableClickZoom: true
  69.                     });
  70.                     loadForm();
  71.                 });
  72.                 function loadRoutes() {
  73.                     $.ajax({
  74.                         url:routesUrl,
  75.                         dataType: "json",
  76.                         async: false,
  77.                         success: function (routes) {
  78.                             Routing.setRoutingData(routes);
  79.                         },
  80.                         error: function (xhr, ajaxOptions, thrownError) {}
  81.                     });
  82.                 }
  83.                 function setFormSubmitListener() {
  84.                     document.querySelector("form[name="+formName+"]").addEventListener('submit', function(e){
  85.                         e.preventDefault();
  86.                         if(!clusterer)
  87.                             return;
  88.                         filterData();
  89.                         return false;
  90.                     });
  91.                 }
  92.                 function loadForm() {
  93.                     fetch('{{ path('map.form', {city: cityUriIdentity}) }}', {
  94.                         mode: "cors",
  95.                         importance: "low",
  96.                         method: "POST",
  97.                         headers: {
  98.                             "Content-Type": "application/x-www-form-urlencoded",
  99.                             "X-Requested-With": "XMLHttpRequest"
  100.                         },
  101.                     }).then(response => {
  102.                         if (response.status < 300) {
  103.                             return response.text();
  104.                         } else {
  105.                             console.warn("🤔");
  106.                             return null;
  107.                         }
  108.                     }).then(response => {
  109.                         document.querySelector('#map_form').innerHTML = response;
  110.                         filterData();
  111.                         setFormSubmitListener();
  112.                     });
  113.                 }
  114.                 function filterData() {
  115.                     preloader.style.display = 'block';
  116.                     var data = {};
  117.                     $("form[name="+formName+"]").serializeArray().forEach((object)=>{
  118.                         //"подгоняем" данные под формат, ожидаемый формой при сабмите
  119.                         var fieldName = object.name.toString().replace(formName + '[', '').replace(']', '');
  120.                         var clearFieldName = fieldName.substr(0, fieldName.indexOf('['));
  121.                         if(~fieldName.indexOf('[]')) {
  122.                             checkArrayIsInFormObject(clearFieldName, data);
  123.                             data[clearFieldName].push(object.value);
  124.                         } else if(~fieldName.indexOf('[m')) {
  125.                             if(!object.value)
  126.                                 return;
  127.                             checkObjectIsInFormObject(clearFieldName, data);
  128.                             if(~fieldName.indexOf('[min]'))
  129.                                 data[clearFieldName]['min'] = object.value;
  130.                             if(~fieldName.indexOf('[max]'))
  131.                                 data[clearFieldName]['max'] = object.value;
  132.                         } else {
  133.                             data[fieldName] = object.value;
  134.                         }
  135.                     });
  136.                     $.ajax({
  137.                         url:'{{ path('map.filter', {city:cityUriIdentity}) }}',
  138.                         type: "POST",
  139.                         dataType: "json",
  140.                         data: {
  141.                             "form": JSON.stringify(data),
  142.                         },
  143.                         async: true,
  144.                         success: function (return_data) {
  145.                             // console.log(return_data);
  146.                             updateMap(return_data);
  147.                             preloader.style.display = 'none';
  148.                         },
  149.                         error: function (xhr, ajaxOptions, thrownError) {}
  150.                     });
  151.                 }
  152.                 function checkArrayIsInFormObject(name, formObject) {
  153.                     if(false == formObject.hasOwnProperty(name))
  154.                         formObject[name] = [];
  155.                 }
  156.                 function checkObjectIsInFormObject(name, formObject) {
  157.                     if(false == formObject.hasOwnProperty(name))
  158.                         formObject[name] = {};
  159.                 }
  160.                 function updateMap(points) {
  161.                     clusterer.removeAll();
  162.                     if(!points || !points.length)
  163.                         return;
  164.                     var getImgUrl = function(path, imgType) {
  165.                         if(path[0] == '/')
  166.                             return path;
  167.                         var assetPackagePath = '';
  168.                         if(imgType == 'avatar')
  169.                             assetPackagePath = avatarPath;
  170.                         else if(imgType == 'photo')
  171.                             assetPackagePath = photoPath;
  172.                         if(imgType == 'thumb')
  173.                             assetPackagePath = thumbPath;
  174.                         return assetPackagePath + path;
  175.                     };
  176.                     var getPointData = function (index) {
  177.                         const data = points[index];
  178.                         const isProfile = data[0] == 1;
  179.                         const isSaloon = data[0] == 2;
  180.                         let url = '';
  181.                         const uri = data[3];
  182.                         if(isProfile) {
  183.                             url = RoutingDecorator.generate(
  184.                                 'profile_preview.page',
  185.                                 multipleCities ? {city: cityUriIdentity, profile: uri} : {profile: uri}
  186.                             );
  187.                         } else if(isSaloon) {
  188.                             url = RoutingDecorator.generate(
  189.                                 'saloon_preview.page',
  190.                                 multipleCities ? {city: cityUriIdentity, saloon: uri} : {saloon: uri}
  191.                             );
  192.                         }
  193.                         var processProfileShowsUrl = '{{ path('map.increment_profile_shows', multipleCities ? {city:cityUriIdentity} : {}) }}';
  194.                         return {
  195.                             balloonContentHeader: '',
  196.                             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>'
  197.                                 + '<img style="display:none;" width="0" height="0" src="' + processProfileShowsUrl + '?id=' + (isProfile ? data[9] : null)+'" />', //не убирать, функционально важно
  198.                             balloonContentFooter: '<font size=1>' + data[8] + ',' + data[9] + ',' + data[10] + '</strong>',
  199.                             clusterCaption: '<strong>' + (isSaloon ? 'Салон ' : '') + data[4] + '</strong>'
  200.                         };
  201.                     };
  202.                     var getPointOptions = function (index, type) {
  203.                         return {
  204.                             preset: type == 'profile' ? 'islands#violetIcon' : 'islands#redIcon'
  205.                         };
  206.                     };
  207.                     var geoObjects = [];
  208.                     for(var i = 0, len = points.length; i < len; i++)
  209.                         geoObjects[i] = new ymaps.Placemark([points[i][1], points[i][2]], getPointData(i), getPointOptions(i, points[i][0] == 1));
  210.                     //В кластеризатор можно добавить javascript-массив меток (не геоколлекцию) или одну метку.
  211.                     clusterer.add(geoObjects);
  212.                     myMap.geoObjects.add(clusterer);
  213.                     // Спозиционируем карту так, чтобы на ней были видны все объекты.
  214.                     myMap.setBounds(clusterer.getBounds(), {
  215.                         checkZoomRange: true
  216.                     });
  217.                 }
  218.             });
  219.         })();
  220.     </script>
  221. {% endblock %}