<div class="container-fluid">
 <div class="row">
 <div class="col-12">
 <div class="card shadow-sm mb-3">
 <div class="card-header d-flex justify-content-between align-items-center">
 <div>
 <h5 class="mb-0">Редактирование участков</h5>
 <?php if(!empty($cat->cat_name)): ?>
 <small class="text-muted d-block">Раздел: <?php echo \htmlentities($cat->cat_name, ENT_QUOTES, 'UTF-8', false); ?></small>
 <?php endif; ?>
 </div>
 <button type="button" class="btn btn-primary btn-sm" id="btn-create-zone">
 <i class="fa fa-draw-polygon mr-1"></i> Создать участок
 </button>
 </div>

 <div class="card-body p-0">
 <div id="map" class="w-100 map-container"></div>
 </div>
 </div>
 </div>
 </div>
</div>

<style>
 #newzoneedit {
 display: none;
 }

 .map-container {
 height: 600px;
 min-height: 400px;
 }

 .balloon-response {
 font-size: 0.875rem;
 }
</style>

<script type="text/javascript" src="assets/js/jquery.ajaxform.js"></script>
<script src="//api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>

<script>
 // Конфиг для запросов
 var POLYGON_CONFIG = {
 baseUrl: <?php echo json_encode('?cat=' . $cat->cat, 15, 512); ?> // строка вида "?cat=admin_polygon"
 };

 var PolygonEditor = {
 myMap: null,
 myPolygon: null,
 isDrawing: false,
 poligons: {},

 init: function () {
 var self = this;

 self.myMap = new ymaps.Map('map', {
 center: [59.859605, 30.340733],
 zoom: 14,
 controls: ['smallMapDefaultSet']
 });

 // Кнопка создания участка
 $('#btn-create-zone').on('click', function () {
 if (!self.isDrawing) {
 self.startDrawing();
 } else {
 self.cancelDrawing();
 }
 });

 // Рендер существующих участков
 <?php if(!empty($rows)): ?>
 <?php $__currentLoopData = $rows; $this->addLoop($__currentLoopData);$this->getFirstLoop();
 foreach($__currentLoopData as $row): $loop = $this->incrementLoopIndices();  ?>
 self.addPolygon(
 <?php echo $row['coords']; ?>,
 <?php echo \htmlentities((int)$row['id'], ENT_QUOTES, 'UTF-8', false); ?>,
 <?php echo json_encode($row['title']); ?>

 );
 <?php endforeach; $this->popLoop(); $loop = $this->getFirstLoop(); ?>
 <?php endif; ?>
 },

 setDrawButtonState: function (active) {
 this.isDrawing = !!active;
 var $btn = $('#btn-create-zone');

 if (this.isDrawing) {
 $btn
 .removeClass('btn-primary')
 .addClass('btn-danger')
 .html('<i class="fa fa-check mr-1"></i> Завершить рисование');
 } else {
 $btn
 .removeClass('btn-danger')
 .addClass('btn-primary')
 .html('<i class="fa fa-draw-polygon mr-1"></i> Создать участок');
 }
 },

 startDrawing: function () {
 var self = this;

 if (self.isDrawing) {
 return;
 }

 self.myPolygon = new ymaps.Polygon([], {}, {
 editorDrawingCursor: "crosshair",
 editorMaxPoints: 999,
 fillColor: '#ed4543',
 strokeColor: '#ed4543',
 fillOpacity: 0.6,
 strokeWidth: 1
 });

 self.myMap.geoObjects.add(self.myPolygon);

 self.attachEditorMonitor(self.myPolygon, function () {
 self.stopDrawing();
 });

 self.myPolygon.editor.startDrawing();
 self.setDrawButtonState(true);
 },

 cancelDrawing: function () {
 if (!this.myPolygon) {
 this.setDrawButtonState(false);
 return;
 }

 this.myPolygon.editor.stopDrawing();
 this.myMap.geoObjects.remove(this.myPolygon);
 this.myPolygon = null;
 this.setDrawButtonState(false);
 },

 stopDrawing: function () {
 var self = this;

 if (!self.myPolygon) {
 self.setDrawButtonState(false);
 return;
 }

 var coords = self.myPolygon.geometry.getCoordinates();
 self.myPolygon.editor.stopDrawing();
 self.myMap.geoObjects.remove(self.myPolygon);
 self.myPolygon = null;

 self.setDrawButtonState(false);

 // ВАЖНО: используем сигнатуру $.post(url, data, success, dataType)
 $.post(
 POLYGON_CONFIG.baseUrl + '&act=editgeom&id=0',
 { geom: coords },
 function (data) {
 if (data && data.id && data.id !== 0) {
 self.addPolygon(coords, data.id, data.title || '');
 }
 },
 'json'
 ).fail(function () {
 console.error('Ошибка сохранения нового участка');
 });
 },

 addPolygon: function (coords, id, title) {
 var self = this;

 // $.get(url, success, dataType)
 $.get(
 POLYGON_CONFIG.baseUrl + '&act=getForm&id=' + id,
 function (params) {
 params = params || {};
 self._addPolygonHtml(
 coords,
 id,
 params.title || title || '',
 params.html || '',
 params.color || '#00FF00'
 );
 },
 'json'
 ).fail(function () {
 console.error('Ошибка получения формы участка');
 });
 },

 _addPolygonHtml: function (coords, id, title, html, fillcolor) {
 var self = this;
 fillcolor = fillcolor || "#00FF00";

 self.poligons[id] = new ymaps.GeoObject({
 geometry: {
 type: "Polygon",
 coordinates: coords,
 fillRule: "nonZero"
 },
 properties: {
 myid: id,
 balloonContentHeader: title,
 balloonContent: html,
 balloonContentFooter:
 '<div class="mt-2">' +
 '<a href="#" onclick="PolygonEditor.editPolygon(' + id + ');return false;">Редактировать контур</a>' +
 ' | ' +
 '<a href="#" class="text-danger" onclick="PolygonEditor.removePolygon(' + id + ');return false;">Удалить участок</a>' +
 '</div>'
 }
 }, {
 fillColor: fillcolor,
 strokeColor: '#0000FF',
 opacity: 0.5,
 strokeWidth: 1,
 strokeStyle: 'shortdash'
 });

 self.attachEditorMonitor(self.poligons[id], function (e) {
 if (e.originalEvent && e.originalEvent.target) {
 var tid     = e.originalEvent.target.properties.get('myid');
 var tcoords = e.originalEvent.target.geometry.getCoordinates();

 if (!tid) {
 self.stopDrawing();
 return;
 }

 $.post(
 POLYGON_CONFIG.baseUrl + '&act=editgeom&id=' + tid,
 { geom: tcoords },
 function (data) {
 if (data && data.id && data.id !== 0) {
 self.addPolygon(tcoords, data.id, data.title || '');
 }
 },
 'json'
 ).fail(function () {
 console.error('Ошибка обновления контура участка');
 });
 }
 });

 self.myMap.geoObjects.add(self.poligons[id]);
 },

 editPolygon: function (id) {
 var polygon = this.poligons[id];
 if (!polygon) {
 return;
 }

 var self = this;

 self.myPolygon = polygon;
 self.myMap.geoObjects.add(self.myPolygon);

 self.attachEditorMonitor(self.myPolygon, function () {
 self.stopDrawing();
 });

 self.myPolygon.editor.startDrawing();
 self.setDrawButtonState(true);
 },

 removePolygon: function (id) {
 var self = this;

 if (!self.poligons[id]) {
 return;
 }

 $.get(
 POLYGON_CONFIG.baseUrl + '&act=remove&id=' + id,
 function () {
 self.myMap.geoObjects.remove(self.poligons[id]);
 delete self.poligons[id];
 }
 ).fail(function () {
 console.error('Ошибка удаления участка');
 });
 },

 submitForm: function (id, idn) {
 var self  = this;
 var $resp = $('#resp' + idn);

 var options = {
 dataType: 'json',
 success: function (params) {
 params = params || {};
 var data = params.html || '';

 $resp
 .addClass('balloon-response')
 .html('<span class="text-success">Данные сохранены</span>' + data);

 if (self.poligons[id]) {
 self.poligons[id].properties.set('balloonContent', data);
 if (params.color) {
 self.poligons[id].options.set('fillColor', params.color);
 }
 }
 },
 error: function () {
 $resp
 .addClass('balloon-response')
 .html('<span class="text-danger">Ошибка сохранения</span>');
 }
 };

 $('#form' + idn).ajaxSubmit(options);
 $resp.html("<img src='img/loader.gif' alt='' class='img-fluid'>");

 return false;
 },

 attachEditorMonitor: function (polygon, onStopCallback) {
 var stateMonitor = new ymaps.Monitor(polygon.editor.state);
 stateMonitor.add("drawing", function (newValue) {
 polygon.options.set("strokeColor", newValue ? '#FF0000' : '#0000FF');
 });

 polygon.events.add(['editorstatechange'], function (e) {
 if (
 e.originalEvent &&
 e.originalEvent.originalEvent &&
 e.originalEvent.originalEvent.originalEvent &&
 e.originalEvent.originalEvent.originalEvent.newDrawing === false &&
 e.originalEvent.originalEvent.originalEvent.oldDrawing === true
 ) {
 if (typeof onStopCallback === 'function') {
 onStopCallback(e);
 }
 }
 });
 }
 };

 // Для совместимости со старой формой: onsubmit="return submit_form(id, idn)"
 function submit_form(id, idn) {
 return PolygonEditor.submitForm(id, idn);
 }

 ymaps.ready(function () {
 PolygonEditor.init();
 });
</script>
