Виджет для формы выбора зеркал
This commit is contained in:
@@ -6,27 +6,93 @@
|
||||
{% block title %}{% if object %}Редактировать объект: {{ object.name }}{% else %}Создать объект{% endif %}{% endblock %}
|
||||
|
||||
{% block extra_css %}
|
||||
<link rel="stylesheet" href="{% static 'css/checkbox-select-multiple.css' %}">
|
||||
<style>
|
||||
.form-section { margin-bottom: 2rem; border: 1px solid #dee2e6; border-radius: 0.25rem; padding: 1rem; }
|
||||
.form-section-header { border-bottom: 1px solid #dee2e6; padding-bottom: 0.5rem; margin-bottom: 1rem; }
|
||||
.btn-action { margin-right: 0.5rem; }
|
||||
.dynamic-form { border: 1px dashed #ced4da; padding: 1rem; margin-top: 1rem; border-radius: 0.25rem; }
|
||||
.dynamic-form-header { display: flex; justify-content: space-between; align-items: center; }
|
||||
.readonly-field { background-color: #f8f9fa; padding: 0.375rem 0.75rem; border: 1px solid #ced4da; border-radius: 0.25rem; }
|
||||
.coord-group { border: 1px solid #dee2e6; padding: 0.75rem; border-radius: 0.25rem; margin-bottom: 1rem; }
|
||||
.coord-group-header { font-weight: bold; margin-bottom: 0.5rem; }
|
||||
.form-check-input { margin-top: 0.25rem; }
|
||||
.datetime-group { display: flex; gap: 1rem; }
|
||||
.datetime-group > div { flex: 1; }
|
||||
#map { height: 500px; width: 100%; margin-bottom: 1rem; }
|
||||
.map-container { margin-bottom: 1rem; }
|
||||
.coord-sync-group { border: 1px solid #dee2e6; padding: 0.75rem; border-radius: 0.25rem; }
|
||||
.form-section {
|
||||
margin-bottom: 2rem;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 0.25rem;
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.form-section-header {
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
padding-bottom: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.dynamic-form {
|
||||
border: 1px dashed #ced4da;
|
||||
padding: 1rem;
|
||||
margin-top: 1rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.dynamic-form-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.readonly-field {
|
||||
background-color: #f8f9fa;
|
||||
padding: 0.375rem 0.75rem;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.coord-group {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.25rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.coord-group-header {
|
||||
font-weight: bold;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
.datetime-group {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.datetime-group>div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
#map {
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.map-container {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.coord-sync-group {
|
||||
border: 1px solid #dee2e6;
|
||||
padding: 0.75rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.map-controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 1rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.map-control-btn {
|
||||
padding: 0.375rem 0.75rem;
|
||||
border: 1px solid #ced4da;
|
||||
@@ -34,25 +100,43 @@
|
||||
border-radius: 0.25rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.map-control-btn.active {
|
||||
background-color: #e9ecef;
|
||||
border-color: #dee2e6;
|
||||
}
|
||||
|
||||
.map-control-btn.edit {
|
||||
background-color: #fff3cd;
|
||||
border-color: #ffeeba;
|
||||
}
|
||||
|
||||
.map-control-btn.save {
|
||||
background-color: #d1ecf1;
|
||||
border-color: #bee5eb;
|
||||
}
|
||||
|
||||
.map-control-btn.cancel {
|
||||
background-color: #f8d7da;
|
||||
border-color: #f5c6cb;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon {
|
||||
filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.3));
|
||||
}
|
||||
|
||||
/* Select2 custom styling */
|
||||
.select2-container--default .select2-selection--multiple {
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
min-height: 38px;
|
||||
}
|
||||
|
||||
.select2-container--default.select2-container--focus .select2-selection--multiple {
|
||||
border-color: #86b7fe;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -65,10 +149,12 @@
|
||||
{% if user.customuser.role == 'admin' or user.customuser.role == 'moderator' %}
|
||||
<button type="submit" form="objitem-form" class="btn btn-primary btn-action">Сохранить</button>
|
||||
{% if object %}
|
||||
<a href="{% url 'mainapp:objitem_delete' object.id %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-action">Удалить</a>
|
||||
<a href="{% url 'mainapp:objitem_delete' object.id %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}"
|
||||
class="btn btn-danger btn-action">Удалить</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<a href="{% url 'mainapp:objitem_list' %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-secondary btn-action">Назад</a>
|
||||
<a href="{% url 'mainapp:objitem_list' %}{% if request.GET.urlencode %}?{{ request.GET.urlencode }}{% endif %}"
|
||||
class="btn btn-secondary btn-action">Назад</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -186,16 +272,16 @@
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="id_geo_latitude" class="form-label">Широта:</label>
|
||||
<input type="number" step="0.000001" class="form-control"
|
||||
id="id_geo_latitude" name="geo_latitude"
|
||||
<input type="number" step="0.000001" class="form-control" id="id_geo_latitude"
|
||||
name="geo_latitude"
|
||||
value="{% if object.geo_obj and object.geo_obj.coords %}{{ object.geo_obj.coords.y|unlocalize }}{% endif %}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="mb-3">
|
||||
<label for="id_geo_longitude" class="form-label">Долгота:</label>
|
||||
<input type="number" step="0.000001" class="form-control"
|
||||
id="id_geo_longitude" name="geo_longitude"
|
||||
<input type="number" step="0.000001" class="form-control" id="id_geo_longitude"
|
||||
name="geo_longitude"
|
||||
value="{% if object.geo_obj and object.geo_obj.coords %}{{ object.geo_obj.coords.x|unlocalize }}{% endif %}">
|
||||
</div>
|
||||
</div>
|
||||
@@ -218,15 +304,13 @@
|
||||
<div class="datetime-group">
|
||||
<div>
|
||||
<label for="id_timestamp_date" class="form-label">Дата:</label>
|
||||
<input type="date" class="form-control"
|
||||
id="id_timestamp_date" name="timestamp_date"
|
||||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|date:'Y-m-d' }}{% endif %}">
|
||||
<input type="date" class="form-control" id="id_timestamp_date" name="timestamp_date"
|
||||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|date:'Y-m-d' }}{% endif %}">
|
||||
</div>
|
||||
<div>
|
||||
<label for="id_timestamp_time" class="form-label">Время:</label>
|
||||
<input type="time" class="form-control"
|
||||
id="id_timestamp_time" name="timestamp_time"
|
||||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|time:'H:i' }}{% endif %}">
|
||||
<input type="time" class="form-control" id="id_timestamp_time" name="timestamp_time"
|
||||
value="{% if object.geo_obj and object.geo_obj.timestamp %}{{ object.geo_obj.timestamp|time:'H:i' }}{% endif %}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -253,201 +337,204 @@
|
||||
{% leaflet_css %}
|
||||
<script src="{% static 'leaflet-markers/js/leaflet-color-markers.js' %}"></script>
|
||||
|
||||
<!-- Подключаем кастомный виджет для мультивыбора -->
|
||||
<script src="{% static 'js/checkbox-select-multiple.js' %}"></script>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Инициализация карты
|
||||
const map = L.map('map').setView([55.75, 37.62], 5);
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Инициализация карты
|
||||
const map = L.map('map').setView([55.75, 37.62], 5);
|
||||
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
||||
}).addTo(map);
|
||||
|
||||
// Функция для создания иконки маркера
|
||||
function createMarkerIcon() {
|
||||
return L.icon({
|
||||
iconUrl: '{% static "leaflet-markers/img/marker-icon-blue.png" %}',
|
||||
shadowUrl: `{% static 'leaflet-markers/img/marker-shadow.png' %}`,
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
popupAnchor: [1, -34],
|
||||
shadowSize: [41, 41]
|
||||
});
|
||||
}
|
||||
const editableLayerGroup = new L.FeatureGroup();
|
||||
map.addLayer(editableLayerGroup);
|
||||
|
||||
// Маркер геолокации
|
||||
const marker = L.marker([55.75, 37.62], {
|
||||
draggable: false,
|
||||
icon: createMarkerIcon(),
|
||||
title: 'Геолокация'
|
||||
}).addTo(editableLayerGroup);
|
||||
marker.bindPopup('Геолокация');
|
||||
|
||||
// Синхронизация при изменении формы
|
||||
function syncFromForm() {
|
||||
const lat = parseFloat(document.getElementById('id_geo_latitude').value);
|
||||
const lng = parseFloat(document.getElementById('id_geo_longitude').value);
|
||||
if (!isNaN(lat) && !isNaN(lng)) {
|
||||
marker.setLatLng([lat, lng]);
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронизация при перетаскивании (только если активировано)
|
||||
marker.on('dragend', function(event) {
|
||||
const latLng = event.target.getLatLng();
|
||||
document.getElementById('id_geo_latitude').value = latLng.lat.toFixed(6);
|
||||
document.getElementById('id_geo_longitude').value = latLng.lng.toFixed(6);
|
||||
});
|
||||
|
||||
// Добавляем методы для управления
|
||||
marker.enableEditing = function() {
|
||||
this.dragging.enable();
|
||||
this.openPopup();
|
||||
};
|
||||
|
||||
marker.disableEditing = function() {
|
||||
this.dragging.disable();
|
||||
this.closePopup();
|
||||
};
|
||||
|
||||
marker.syncFromForm = syncFromForm;
|
||||
|
||||
// Устанавливаем начальные координаты из полей формы
|
||||
function initMarkersFromForm() {
|
||||
const geoLat = parseFloat(document.getElementById('id_geo_latitude').value) || 55.75;
|
||||
const geoLng = parseFloat(document.getElementById('id_geo_longitude').value) || 37.62;
|
||||
marker.setLatLng([geoLat, geoLng]);
|
||||
|
||||
// Центрируем карту на маркере
|
||||
map.setView(marker.getLatLng(), 10);
|
||||
}
|
||||
|
||||
// Настройка формы для синхронизации с маркером
|
||||
function setupFormChange(latFieldId, lngFieldId, marker) {
|
||||
const latField = document.getElementById(latFieldId);
|
||||
const lngField = document.getElementById(lngFieldId);
|
||||
|
||||
[latField, lngField].forEach(field => {
|
||||
field.addEventListener('change', function() {
|
||||
const lat = parseFloat(latField.value);
|
||||
const lng = parseFloat(lngField.value);
|
||||
|
||||
if (!isNaN(lat) && !isNaN(lng)) {
|
||||
marker.setLatLng([lat, lng]);
|
||||
map.setView(marker.getLatLng(), 10);
|
||||
}
|
||||
// Функция для создания иконки маркера
|
||||
function createMarkerIcon() {
|
||||
return L.icon({
|
||||
iconUrl: '{% static "leaflet-markers/img/marker-icon-blue.png" %}',
|
||||
shadowUrl: `{% static 'leaflet-markers/img/marker-shadow.png' %}`,
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
popupAnchor: [1, -34],
|
||||
shadowSize: [41, 41]
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const editableLayerGroup = new L.FeatureGroup();
|
||||
map.addLayer(editableLayerGroup);
|
||||
|
||||
// Инициализация
|
||||
initMarkersFromForm();
|
||||
// Настройка формы для синхронизации с маркером
|
||||
setupFormChange('id_geo_latitude', 'id_geo_longitude', marker);
|
||||
// --- УПРАВЛЕНИЕ РЕДАКТИРОВАНИЕМ ---
|
||||
// Кнопки редактирования
|
||||
const editControlsDiv = L.DomUtil.create('div', 'map-controls');
|
||||
editControlsDiv.style.position = 'absolute';
|
||||
editControlsDiv.style.top = '10px';
|
||||
editControlsDiv.style.right = '10px';
|
||||
editControlsDiv.style.zIndex = '1000';
|
||||
editControlsDiv.style.background = 'white';
|
||||
editControlsDiv.style.padding = '10px';
|
||||
editControlsDiv.style.borderRadius = '4px';
|
||||
editControlsDiv.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||||
editControlsDiv.innerHTML = `
|
||||
// Маркер геолокации
|
||||
const marker = L.marker([55.75, 37.62], {
|
||||
draggable: false,
|
||||
icon: createMarkerIcon(),
|
||||
title: 'Геолокация'
|
||||
}).addTo(editableLayerGroup);
|
||||
marker.bindPopup('Геолокация');
|
||||
|
||||
// Синхронизация при изменении формы
|
||||
function syncFromForm() {
|
||||
const lat = parseFloat(document.getElementById('id_geo_latitude').value);
|
||||
const lng = parseFloat(document.getElementById('id_geo_longitude').value);
|
||||
if (!isNaN(lat) && !isNaN(lng)) {
|
||||
marker.setLatLng([lat, lng]);
|
||||
}
|
||||
}
|
||||
|
||||
// Синхронизация при перетаскивании (только если активировано)
|
||||
marker.on('dragend', function (event) {
|
||||
const latLng = event.target.getLatLng();
|
||||
document.getElementById('id_geo_latitude').value = latLng.lat.toFixed(6);
|
||||
document.getElementById('id_geo_longitude').value = latLng.lng.toFixed(6);
|
||||
});
|
||||
|
||||
// Добавляем методы для управления
|
||||
marker.enableEditing = function () {
|
||||
this.dragging.enable();
|
||||
this.openPopup();
|
||||
};
|
||||
|
||||
marker.disableEditing = function () {
|
||||
this.dragging.disable();
|
||||
this.closePopup();
|
||||
};
|
||||
|
||||
marker.syncFromForm = syncFromForm;
|
||||
|
||||
// Устанавливаем начальные координаты из полей формы
|
||||
function initMarkersFromForm() {
|
||||
const geoLat = parseFloat(document.getElementById('id_geo_latitude').value) || 55.75;
|
||||
const geoLng = parseFloat(document.getElementById('id_geo_longitude').value) || 37.62;
|
||||
marker.setLatLng([geoLat, geoLng]);
|
||||
|
||||
// Центрируем карту на маркере
|
||||
map.setView(marker.getLatLng(), 10);
|
||||
}
|
||||
|
||||
// Настройка формы для синхронизации с маркером
|
||||
function setupFormChange(latFieldId, lngFieldId, marker) {
|
||||
const latField = document.getElementById(latFieldId);
|
||||
const lngField = document.getElementById(lngFieldId);
|
||||
|
||||
[latField, lngField].forEach(field => {
|
||||
field.addEventListener('change', function () {
|
||||
const lat = parseFloat(latField.value);
|
||||
const lng = parseFloat(lngField.value);
|
||||
|
||||
if (!isNaN(lat) && !isNaN(lng)) {
|
||||
marker.setLatLng([lat, lng]);
|
||||
map.setView(marker.getLatLng(), 10);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Инициализация
|
||||
initMarkersFromForm();
|
||||
// Настройка формы для синхронизации с маркером
|
||||
setupFormChange('id_geo_latitude', 'id_geo_longitude', marker);
|
||||
// --- УПРАВЛЕНИЕ РЕДАКТИРОВАНИЕМ ---
|
||||
// Кнопки редактирования
|
||||
const editControlsDiv = L.DomUtil.create('div', 'map-controls');
|
||||
editControlsDiv.style.position = 'absolute';
|
||||
editControlsDiv.style.top = '10px';
|
||||
editControlsDiv.style.right = '10px';
|
||||
editControlsDiv.style.zIndex = '1000';
|
||||
editControlsDiv.style.background = 'white';
|
||||
editControlsDiv.style.padding = '10px';
|
||||
editControlsDiv.style.borderRadius = '4px';
|
||||
editControlsDiv.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||||
editControlsDiv.innerHTML = `
|
||||
<div class="map-controls">
|
||||
<button type="button" id="edit-btn" class="map-control-btn edit">Редактировать</button>
|
||||
<button type="button" id="save-btn" class="map-control-btn save" disabled>Сохранить</button>
|
||||
<button type="button" id="cancel-btn" class="map-control-btn cancel" disabled>Отмена</button>
|
||||
</div>
|
||||
`;
|
||||
map.getContainer().appendChild(editControlsDiv);
|
||||
map.getContainer().appendChild(editControlsDiv);
|
||||
|
||||
let isEditing = false;
|
||||
let isEditing = false;
|
||||
|
||||
// Сохраняем начальные координаты для отмены
|
||||
const initialPosition = marker.getLatLng();
|
||||
// Сохраняем начальные координаты для отмены
|
||||
const initialPosition = marker.getLatLng();
|
||||
|
||||
// Включение редактирования
|
||||
document.getElementById('edit-btn').addEventListener('click', function() {
|
||||
if (isEditing) return;
|
||||
// Включение редактирования
|
||||
document.getElementById('edit-btn').addEventListener('click', function () {
|
||||
if (isEditing) return;
|
||||
|
||||
isEditing = true;
|
||||
document.getElementById('edit-btn').classList.add('active');
|
||||
document.getElementById('save-btn').disabled = false;
|
||||
document.getElementById('cancel-btn').disabled = false;
|
||||
isEditing = true;
|
||||
document.getElementById('edit-btn').classList.add('active');
|
||||
document.getElementById('save-btn').disabled = false;
|
||||
document.getElementById('cancel-btn').disabled = false;
|
||||
|
||||
// Включаем drag для маркера
|
||||
marker.enableEditing();
|
||||
// Включаем drag для маркера
|
||||
marker.enableEditing();
|
||||
|
||||
// Показываем подсказку
|
||||
L.popup()
|
||||
.setLatLng(map.getCenter())
|
||||
.setContent('Перетаскивайте маркер. Нажмите "Сохранить" или "Отмена".')
|
||||
.openOn(map);
|
||||
});
|
||||
// Показываем подсказку
|
||||
L.popup()
|
||||
.setLatLng(map.getCenter())
|
||||
.setContent('Перетаскивайте маркер. Нажмите "Сохранить" или "Отмена".')
|
||||
.openOn(map);
|
||||
});
|
||||
|
||||
// Сохранение изменений
|
||||
document.getElementById('save-btn').addEventListener('click', function() {
|
||||
if (!isEditing) return;
|
||||
// Сохранение изменений
|
||||
document.getElementById('save-btn').addEventListener('click', function () {
|
||||
if (!isEditing) return;
|
||||
|
||||
isEditing = false;
|
||||
document.getElementById('edit-btn').classList.remove('active');
|
||||
document.getElementById('save-btn').disabled = true;
|
||||
document.getElementById('cancel-btn').disabled = true;
|
||||
isEditing = false;
|
||||
document.getElementById('edit-btn').classList.remove('active');
|
||||
document.getElementById('save-btn').disabled = true;
|
||||
document.getElementById('cancel-btn').disabled = true;
|
||||
|
||||
// Отключаем редактирование
|
||||
marker.disableEditing();
|
||||
// Отключаем редактирование
|
||||
marker.disableEditing();
|
||||
|
||||
// Обновляем начальную позицию
|
||||
initialPosition.lat = marker.getLatLng().lat;
|
||||
initialPosition.lng = marker.getLatLng().lng;
|
||||
// Обновляем начальную позицию
|
||||
initialPosition.lat = marker.getLatLng().lat;
|
||||
initialPosition.lng = marker.getLatLng().lng;
|
||||
|
||||
// Убираем попап подсказки
|
||||
map.closePopup();
|
||||
});
|
||||
// Убираем попап подсказки
|
||||
map.closePopup();
|
||||
});
|
||||
|
||||
// Отмена изменений
|
||||
document.getElementById('cancel-btn').addEventListener('click', function() {
|
||||
if (!isEditing) return;
|
||||
// Отмена изменений
|
||||
document.getElementById('cancel-btn').addEventListener('click', function () {
|
||||
if (!isEditing) return;
|
||||
|
||||
isEditing = false;
|
||||
document.getElementById('edit-btn').classList.remove('active');
|
||||
document.getElementById('save-btn').disabled = true;
|
||||
document.getElementById('cancel-btn').disabled = true;
|
||||
isEditing = false;
|
||||
document.getElementById('edit-btn').classList.remove('active');
|
||||
document.getElementById('save-btn').disabled = true;
|
||||
document.getElementById('cancel-btn').disabled = true;
|
||||
|
||||
// Возвращаем маркер на исходную позицию
|
||||
marker.setLatLng(initialPosition);
|
||||
// Возвращаем маркер на исходную позицию
|
||||
marker.setLatLng(initialPosition);
|
||||
|
||||
// Отключаем редактирование
|
||||
marker.disableEditing();
|
||||
// Отключаем редактирование
|
||||
marker.disableEditing();
|
||||
|
||||
// Синхронизируем форму с исходным значением
|
||||
document.getElementById('id_geo_latitude').value = initialPosition.lat.toFixed(6);
|
||||
document.getElementById('id_geo_longitude').value = initialPosition.lng.toFixed(6);
|
||||
map.closePopup();
|
||||
});
|
||||
// Синхронизируем форму с исходным значением
|
||||
document.getElementById('id_geo_latitude').value = initialPosition.lat.toFixed(6);
|
||||
document.getElementById('id_geo_longitude').value = initialPosition.lng.toFixed(6);
|
||||
map.closePopup();
|
||||
});
|
||||
|
||||
// Легенда
|
||||
const legend = L.control({ position: 'bottomright' });
|
||||
// Легенда
|
||||
const legend = L.control({ position: 'bottomright' });
|
||||
|
||||
legend.onAdd = function() {
|
||||
const div = L.DomUtil.create('div', 'info legend');
|
||||
div.style.fontSize = '14px';
|
||||
div.style.backgroundColor = 'white';
|
||||
div.style.padding = '10px';
|
||||
div.style.borderRadius = '4px';
|
||||
div.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||||
div.innerHTML = `
|
||||
legend.onAdd = function () {
|
||||
const div = L.DomUtil.create('div', 'info legend');
|
||||
div.style.fontSize = '14px';
|
||||
div.style.backgroundColor = 'white';
|
||||
div.style.padding = '10px';
|
||||
div.style.borderRadius = '4px';
|
||||
div.style.boxShadow = '0 0 10px rgba(0,0,0,0.2)';
|
||||
div.innerHTML = `
|
||||
<h5>Легенда</h5>
|
||||
<div><span style="color: blue; font-weight: bold;">•</span> Геолокация</div>
|
||||
`;
|
||||
return div;
|
||||
};
|
||||
return div;
|
||||
};
|
||||
|
||||
legend.addTo(map);
|
||||
});
|
||||
legend.addTo(map);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,28 @@
|
||||
{% load static %}
|
||||
<div class="checkbox-multiselect-wrapper" data-widget-id="{{ widget.attrs.id }}">
|
||||
<div class="multiselect-input-container">
|
||||
<div class="multiselect-tags" id="{{ widget.attrs.id }}_tags"></div>
|
||||
<input type="text"
|
||||
class="multiselect-search form-control"
|
||||
placeholder="{{ widget.attrs.placeholder|default:'Выберите элементы...' }}"
|
||||
id="{{ widget.attrs.id }}_search"
|
||||
autocomplete="off">
|
||||
<button type="button" class="multiselect-clear" id="{{ widget.attrs.id }}_clear" title="Очистить все">×</button>
|
||||
</div>
|
||||
<div class="multiselect-dropdown" id="{{ widget.attrs.id }}_dropdown">
|
||||
<div class="multiselect-options">
|
||||
{% for group_name, group_choices, group_index in widget.optgroups %}
|
||||
{% for option in group_choices %}
|
||||
<label class="multiselect-option">
|
||||
<input type="checkbox"
|
||||
name="{{ widget.name }}"
|
||||
value="{{ option.value }}"
|
||||
{% if option.selected %}checked{% endif %}
|
||||
data-label="{{ option.label }}">
|
||||
<span class="option-label">{{ option.label }}</span>
|
||||
</label>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user