Geoposicionador de cosas
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* Scripts del admin - FP Geo Content
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
'use strict';
|
||||
|
||||
$(document).ready(function() {
|
||||
// Copiar shortcode al portapapeles
|
||||
$('.fp-geo-shortcode').on('click', function() {
|
||||
const text = $(this).text();
|
||||
navigator.clipboard.writeText(text).then(function() {
|
||||
alert('Shortcode copiado al portapapeles');
|
||||
});
|
||||
}).css('cursor', 'pointer').attr('title', 'Clic para copiar');
|
||||
|
||||
// Media uploader para icono personalizado
|
||||
let mediaUploader;
|
||||
|
||||
$('.fp-geo-upload-btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const targetId = $(this).data('target');
|
||||
const $input = $('#' + targetId);
|
||||
const $preview = $('#' + targetId + '_preview');
|
||||
const $removeBtn = $('.fp-geo-remove-btn[data-target="' + targetId + '"]');
|
||||
|
||||
// Si el uploader ya existe, abrirlo
|
||||
if (mediaUploader) {
|
||||
mediaUploader.open();
|
||||
return;
|
||||
}
|
||||
|
||||
// Crear el media uploader
|
||||
mediaUploader = wp.media({
|
||||
title: 'Seleccionar icono de marcador',
|
||||
button: {
|
||||
text: 'Usar este icono'
|
||||
},
|
||||
multiple: false,
|
||||
library: {
|
||||
type: 'image'
|
||||
}
|
||||
});
|
||||
|
||||
// Cuando se selecciona una imagen
|
||||
mediaUploader.on('select', function() {
|
||||
const attachment = mediaUploader.state().get('selection').first().toJSON();
|
||||
|
||||
// Actualizar input
|
||||
$input.val(attachment.id);
|
||||
|
||||
// Mostrar preview
|
||||
const imgUrl = attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
|
||||
$preview.html('<img src="' + imgUrl + '" alt="" style="max-width: 60px; height: auto;">').show();
|
||||
|
||||
// Mostrar botón eliminar
|
||||
$removeBtn.show();
|
||||
});
|
||||
|
||||
mediaUploader.open();
|
||||
});
|
||||
|
||||
// Eliminar imagen
|
||||
$('.fp-geo-remove-btn').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const targetId = $(this).data('target');
|
||||
const $input = $('#' + targetId);
|
||||
const $preview = $('#' + targetId + '_preview');
|
||||
|
||||
$input.val('');
|
||||
$preview.html('').hide();
|
||||
$(this).hide();
|
||||
});
|
||||
|
||||
// Toggle opciones de color por categoría
|
||||
$('input[name="fp_geo_content_options[use_category_colors]"]').on('change', function() {
|
||||
const $options = $('.fp-geo-category-color-options');
|
||||
if ($(this).is(':checked')) {
|
||||
$options.slideDown();
|
||||
} else {
|
||||
$options.slideUp();
|
||||
}
|
||||
}).trigger('change');
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -0,0 +1,630 @@
|
||||
/**
|
||||
* Script del mapa - FP Geo Content
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Almacenar instancias de mapas
|
||||
const mapInstances = {};
|
||||
|
||||
/**
|
||||
* Inicializar cuando el DOM esté listo
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Buscar todos los wrappers de mapas
|
||||
document.querySelectorAll('.fp-geo-wrapper').forEach(function(wrapper) {
|
||||
const instance = wrapper.dataset.instance;
|
||||
const configName = 'fpGeoConfig_' + instance;
|
||||
|
||||
if (window[configName]) {
|
||||
initMap(window[configName]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Inicializar un mapa
|
||||
*/
|
||||
function initMap(config) {
|
||||
const mapEl = document.getElementById(config.mapId);
|
||||
if (!mapEl) return;
|
||||
|
||||
// Configurar opciones de scroll wheel zoom
|
||||
let scrollWheelZoomOption = false;
|
||||
if (config.scrollWheelZoom === 'always') {
|
||||
scrollWheelZoomOption = true;
|
||||
} else if (config.scrollWheelZoom === 'ctrl') {
|
||||
scrollWheelZoomOption = 'ctrl';
|
||||
}
|
||||
|
||||
// Crear mapa Leaflet
|
||||
const map = L.map(mapEl, {
|
||||
center: config.center,
|
||||
zoom: config.zoom,
|
||||
minZoom: config.minZoom,
|
||||
maxZoom: config.maxZoom,
|
||||
scrollWheelZoom: scrollWheelZoomOption === 'ctrl' ? false : scrollWheelZoomOption,
|
||||
});
|
||||
|
||||
// Añadir capa de tiles
|
||||
L.tileLayer(config.tileUrl, {
|
||||
attribution: config.tileAttribution,
|
||||
subdomains: config.tileSubdomains || 'abc',
|
||||
maxZoom: 19,
|
||||
}).addTo(map);
|
||||
|
||||
// Crear grupo de marcadores (con o sin cluster)
|
||||
let markersLayer;
|
||||
if (config.clusterEnabled) {
|
||||
markersLayer = L.markerClusterGroup({
|
||||
showCoverageOnHover: false,
|
||||
maxClusterRadius: 50,
|
||||
});
|
||||
} else {
|
||||
markersLayer = L.layerGroup();
|
||||
}
|
||||
|
||||
// Almacenar datos
|
||||
const mapData = {
|
||||
map: map,
|
||||
markersLayer: markersLayer,
|
||||
allMarkers: [],
|
||||
config: config,
|
||||
activeFilters: {},
|
||||
};
|
||||
|
||||
mapInstances[config.mapId] = mapData;
|
||||
|
||||
// Configurar control de scroll con Ctrl
|
||||
if (config.scrollWheelZoom === 'ctrl') {
|
||||
initCtrlScrollZoom(mapData);
|
||||
}
|
||||
|
||||
// Añadir marcadores iniciales
|
||||
addMarkers(mapData, config.markers);
|
||||
|
||||
// Añadir capa al mapa
|
||||
map.addLayer(markersLayer);
|
||||
|
||||
// Ajustar zoom para mostrar todos los marcadores
|
||||
fitMapToMarkers(mapData);
|
||||
|
||||
// Inicializar filtros
|
||||
initFilters(mapData);
|
||||
|
||||
// Inicializar panel de detalle
|
||||
initDetailPanel(mapData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializar control de zoom con Ctrl+scroll
|
||||
*/
|
||||
function initCtrlScrollZoom(mapData) {
|
||||
const { map, config } = mapData;
|
||||
const mapEl = document.getElementById(config.mapId);
|
||||
let hintTimeout;
|
||||
|
||||
// Crear elemento de aviso
|
||||
const scrollHint = document.createElement('div');
|
||||
scrollHint.className = 'fp-geo-scroll-hint';
|
||||
scrollHint.textContent = config.i18n.scrollZoomHint || 'Usa Ctrl + scroll para hacer zoom';
|
||||
mapEl.parentElement.appendChild(scrollHint);
|
||||
|
||||
// Detectar scroll sin Ctrl
|
||||
mapEl.addEventListener('wheel', function(e) {
|
||||
if (e.ctrlKey) {
|
||||
// Habilitar zoom cuando Ctrl está presionado
|
||||
map.scrollWheelZoom.enable();
|
||||
scrollHint.classList.remove('visible');
|
||||
} else {
|
||||
// Mostrar aviso
|
||||
map.scrollWheelZoom.disable();
|
||||
scrollHint.classList.add('visible');
|
||||
|
||||
clearTimeout(hintTimeout);
|
||||
hintTimeout = setTimeout(function() {
|
||||
scrollHint.classList.remove('visible');
|
||||
}, 1500);
|
||||
}
|
||||
});
|
||||
|
||||
// Deshabilitar zoom al soltar Ctrl
|
||||
document.addEventListener('keyup', function(e) {
|
||||
if (e.key === 'Control') {
|
||||
map.scrollWheelZoom.disable();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajustar el zoom del mapa para mostrar todos los marcadores
|
||||
*/
|
||||
function fitMapToMarkers(mapData) {
|
||||
const { map, markersLayer, config } = mapData;
|
||||
|
||||
// Obtener los límites del grupo de marcadores
|
||||
const layers = markersLayer.getLayers();
|
||||
|
||||
if (layers.length === 0) {
|
||||
// Sin marcadores, usar centro y zoom por defecto
|
||||
return;
|
||||
}
|
||||
|
||||
if (layers.length === 1) {
|
||||
// Un solo marcador: centrar en él con zoom razonable
|
||||
const marker = layers[0];
|
||||
map.setView(marker.getLatLng(), Math.min(config.zoom || 14, config.maxZoom || 18));
|
||||
return;
|
||||
}
|
||||
|
||||
// Varios marcadores: ajustar para mostrar todos
|
||||
const bounds = markersLayer.getBounds();
|
||||
|
||||
if (bounds.isValid()) {
|
||||
map.fitBounds(bounds, {
|
||||
padding: [50, 50], // Margen de 50px
|
||||
maxZoom: config.maxZoom || 18,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crear icono de marcador circular SVG
|
||||
*/
|
||||
function createCircleMarkerIcon(color, isPilot = false) {
|
||||
const size = 36;
|
||||
const strokeWidth = 3;
|
||||
|
||||
// Crear SVG simple y limpio
|
||||
let svg;
|
||||
|
||||
if (isPilot) {
|
||||
// Marcador con estrella para pilotos
|
||||
svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + (size + 12) + '" viewBox="0 0 ' + size + ' ' + (size + 12) + '">' +
|
||||
'<circle cx="' + (size/2) + '" cy="' + (size/2) + '" r="' + (size/2 - 2) + '" fill="rgba(0,0,0,0.3)" transform="translate(2, 2)"/>' +
|
||||
'<circle cx="' + (size/2) + '" cy="' + (size/2) + '" r="' + (size/2 - strokeWidth) + '" fill="' + color + '" stroke="white" stroke-width="' + strokeWidth + '"/>' +
|
||||
'<polygon points="' + (size/2) + ',' + (size + 2) + ' ' + (size/2 + 5) + ',' + (size + 12) + ' ' + (size/2 - 5) + ',' + (size + 12) + '" fill="' + color + '" stroke="white" stroke-width="1"/>' +
|
||||
'<text x="' + (size/2) + '" y="' + (size/2 + 4) + '" text-anchor="middle" fill="white" font-size="14" font-weight="bold">★</text>' +
|
||||
'</svg>';
|
||||
|
||||
return L.divIcon({
|
||||
className: 'fp-geo-circle-marker fp-geo-pilot-marker',
|
||||
html: svg,
|
||||
iconSize: [size, size + 12],
|
||||
iconAnchor: [size/2, size + 12],
|
||||
popupAnchor: [0, -(size + 12)],
|
||||
});
|
||||
} else {
|
||||
// Marcador circular normal con punta
|
||||
svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + size + '" height="' + (size + 12) + '" viewBox="0 0 ' + size + ' ' + (size + 12) + '">' +
|
||||
'<circle cx="' + (size/2) + '" cy="' + (size/2) + '" r="' + (size/2 - 2) + '" fill="rgba(0,0,0,0.3)" transform="translate(2, 2)"/>' +
|
||||
'<circle cx="' + (size/2) + '" cy="' + (size/2) + '" r="' + (size/2 - strokeWidth) + '" fill="' + color + '" stroke="white" stroke-width="' + strokeWidth + '"/>' +
|
||||
'<polygon points="' + (size/2) + ',' + (size + 10) + ' ' + (size/2 + 6) + ',' + (size - 4) + ' ' + (size/2 - 6) + ',' + (size - 4) + '" fill="' + color + '" stroke="white" stroke-width="2" stroke-linejoin="round"/>' +
|
||||
'</svg>';
|
||||
|
||||
return L.divIcon({
|
||||
className: 'fp-geo-circle-marker',
|
||||
html: svg,
|
||||
iconSize: [size, size + 12],
|
||||
iconAnchor: [size/2, size + 10],
|
||||
popupAnchor: [0, -(size + 10)],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Añadir marcadores al mapa
|
||||
*/
|
||||
function addMarkers(mapData, markers) {
|
||||
const { markersLayer, config } = mapData;
|
||||
|
||||
// Limpiar marcadores existentes
|
||||
markersLayer.clearLayers();
|
||||
mapData.allMarkers = [];
|
||||
|
||||
// Color por defecto
|
||||
const defaultColor = config.markerDefaultColor || '#F97316';
|
||||
|
||||
markers.forEach(function(markerData) {
|
||||
let icon;
|
||||
let markerColor = defaultColor;
|
||||
|
||||
// es_piloto viene directamente del post (actuación), no de los términos
|
||||
let isPilot = markerData.es_piloto === true;
|
||||
|
||||
// Buscar color de la taxonomía configurada para colores
|
||||
if (config.useCategoryColors && markerData.taxonomies) {
|
||||
// Primero intentar con la taxonomía de leyenda configurada
|
||||
if (config.legendTaxonomy) {
|
||||
const categoryTerms = markerData.taxonomies[config.legendTaxonomy];
|
||||
if (categoryTerms && categoryTerms.length > 0) {
|
||||
if (categoryTerms[0].color) {
|
||||
markerColor = categoryTerms[0].color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Si no hay color, buscar en cualquier taxonomía
|
||||
if (markerColor === defaultColor) {
|
||||
for (const taxonomy in markerData.taxonomies) {
|
||||
const terms = markerData.taxonomies[taxonomy];
|
||||
if (terms && terms.length > 0 && terms[0].color) {
|
||||
markerColor = terms[0].color;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Usar icono personalizado si existe, o círculo de color
|
||||
if (config.markerIcon && config.markerIcon !== '') {
|
||||
icon = L.icon({
|
||||
iconUrl: config.markerIcon,
|
||||
iconSize: [40, 50],
|
||||
iconAnchor: [20, 50],
|
||||
popupAnchor: [0, -50],
|
||||
});
|
||||
} else {
|
||||
// Crear marcador circular con el color
|
||||
icon = createCircleMarkerIcon(markerColor, isPilot);
|
||||
}
|
||||
|
||||
// Crear marcador
|
||||
const marker = L.marker([markerData.lat, markerData.lng], { icon: icon });
|
||||
|
||||
// Guardar datos en el marcador
|
||||
marker.markerData = markerData;
|
||||
marker.markerColor = markerColor;
|
||||
|
||||
// Evento de clic
|
||||
marker.on('click', function() {
|
||||
showDetail(mapData, markerData);
|
||||
});
|
||||
|
||||
// Añadir al grupo
|
||||
markersLayer.addLayer(marker);
|
||||
mapData.allMarkers.push(marker);
|
||||
});
|
||||
|
||||
// Actualizar contador
|
||||
updateResultsCount(mapData, markers.length);
|
||||
|
||||
// Debug: mostrar en consola cuántos marcadores se añadieron
|
||||
console.log('[FP Geo] Añadidos ' + markers.length + ' marcadores con color por defecto: ' + defaultColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualizar contador de resultados
|
||||
*/
|
||||
function updateResultsCount(mapData, count) {
|
||||
const { config } = mapData;
|
||||
const wrapper = document.getElementById(config.mapId + '-wrapper');
|
||||
if (!wrapper) return;
|
||||
|
||||
const countEl = wrapper.querySelector('.fp-geo-results-number');
|
||||
const labelEl = wrapper.querySelector('.fp-geo-results-label');
|
||||
|
||||
if (countEl) {
|
||||
countEl.textContent = count;
|
||||
}
|
||||
|
||||
if (labelEl) {
|
||||
// Si solo hay un tipo de contenido, mostrar su nombre
|
||||
if (config.postTypes && config.postTypes.length === 1) {
|
||||
const postType = config.postTypes[0];
|
||||
// Usar el nombre del post type en plural/singular
|
||||
const labels = config.postTypeLabels || {};
|
||||
if (count === 1) {
|
||||
labelEl.textContent = labels[postType]?.singular || postType;
|
||||
} else {
|
||||
labelEl.textContent = labels[postType]?.plural || postType + 's';
|
||||
}
|
||||
} else {
|
||||
labelEl.textContent = count === 1 ? 'resultado' : 'resultados';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializar filtros
|
||||
*/
|
||||
function initFilters(mapData) {
|
||||
const { config } = mapData;
|
||||
const wrapper = document.getElementById(config.mapId + '-wrapper');
|
||||
if (!wrapper) return;
|
||||
|
||||
const filtersEl = wrapper.querySelector('.fp-geo-filters');
|
||||
if (!filtersEl) return;
|
||||
|
||||
// Botones de filtro
|
||||
filtersEl.querySelectorAll('.fp-geo-filter-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
const taxonomy = btn.dataset.taxonomy;
|
||||
const slug = btn.dataset.slug;
|
||||
|
||||
// Toggle activo
|
||||
btn.classList.toggle('active');
|
||||
|
||||
// Actualizar filtros activos
|
||||
if (!mapData.activeFilters[taxonomy]) {
|
||||
mapData.activeFilters[taxonomy] = [];
|
||||
}
|
||||
|
||||
const index = mapData.activeFilters[taxonomy].indexOf(slug);
|
||||
if (index > -1) {
|
||||
mapData.activeFilters[taxonomy].splice(index, 1);
|
||||
} else {
|
||||
mapData.activeFilters[taxonomy].push(slug);
|
||||
}
|
||||
|
||||
// Aplicar filtros
|
||||
applyFilters(mapData);
|
||||
});
|
||||
});
|
||||
|
||||
// Botón limpiar
|
||||
const clearBtn = filtersEl.querySelector('.fp-geo-clear-filters');
|
||||
if (clearBtn) {
|
||||
clearBtn.addEventListener('click', function() {
|
||||
// Limpiar todos los filtros
|
||||
mapData.activeFilters = {};
|
||||
filtersEl.querySelectorAll('.fp-geo-filter-btn.active').forEach(function(btn) {
|
||||
btn.classList.remove('active');
|
||||
});
|
||||
applyFilters(mapData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aplicar filtros a los marcadores
|
||||
*/
|
||||
function applyFilters(mapData) {
|
||||
const { markersLayer, allMarkers, activeFilters, config } = mapData;
|
||||
const filterCombine = config.filterCombine || 'OR';
|
||||
|
||||
// Verificar si hay filtros activos
|
||||
const hasActiveFilters = Object.values(activeFilters).some(arr => arr.length > 0);
|
||||
let visibleCount = 0;
|
||||
|
||||
allMarkers.forEach(function(marker) {
|
||||
const data = marker.markerData;
|
||||
let shouldShow = true;
|
||||
|
||||
if (hasActiveFilters) {
|
||||
if (filterCombine === 'AND') {
|
||||
// Debe cumplir TODOS los filtros
|
||||
shouldShow = Object.entries(activeFilters).every(function([taxonomy, slugs]) {
|
||||
if (slugs.length === 0) return true;
|
||||
|
||||
const markerTerms = data.taxonomies && data.taxonomies[taxonomy];
|
||||
if (!markerTerms) return false;
|
||||
|
||||
return slugs.some(function(slug) {
|
||||
return markerTerms.some(function(term) {
|
||||
return term.slug === slug;
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Debe cumplir AL MENOS UN filtro (OR)
|
||||
shouldShow = Object.entries(activeFilters).some(function([taxonomy, slugs]) {
|
||||
if (slugs.length === 0) return false;
|
||||
|
||||
const markerTerms = data.taxonomies && data.taxonomies[taxonomy];
|
||||
if (!markerTerms) return false;
|
||||
|
||||
return slugs.some(function(slug) {
|
||||
return markerTerms.some(function(term) {
|
||||
return term.slug === slug;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Si no hay filtros activos en ninguna taxonomía, mostrar todo
|
||||
if (!Object.values(activeFilters).some(arr => arr.length > 0)) {
|
||||
shouldShow = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldShow) {
|
||||
markersLayer.addLayer(marker);
|
||||
visibleCount++;
|
||||
} else {
|
||||
markersLayer.removeLayer(marker);
|
||||
}
|
||||
});
|
||||
|
||||
// Actualizar contador de resultados
|
||||
updateResultsCount(mapData, visibleCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializar panel de detalle
|
||||
*/
|
||||
function initDetailPanel(mapData) {
|
||||
const { config } = mapData;
|
||||
const wrapper = document.getElementById(config.mapId + '-wrapper');
|
||||
if (!wrapper) return;
|
||||
|
||||
const detailEl = document.getElementById(config.mapId + '-detail');
|
||||
const overlayEl = document.getElementById(config.mapId + '-overlay');
|
||||
|
||||
if (!detailEl) return;
|
||||
|
||||
// Botón cerrar
|
||||
const closeBtn = detailEl.querySelector('.fp-geo-detail-close');
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', function() {
|
||||
hideDetail(mapData);
|
||||
});
|
||||
}
|
||||
|
||||
// Cerrar al hacer clic en overlay (modal)
|
||||
if (overlayEl) {
|
||||
overlayEl.addEventListener('click', function() {
|
||||
hideDetail(mapData);
|
||||
});
|
||||
}
|
||||
|
||||
// Cerrar con Escape
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
hideDetail(mapData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mostrar detalle de un marcador
|
||||
*/
|
||||
function showDetail(mapData, data) {
|
||||
const { config } = mapData;
|
||||
const detailEl = document.getElementById(config.mapId + '-detail');
|
||||
const overlayEl = document.getElementById(config.mapId + '-overlay');
|
||||
|
||||
if (!detailEl) return;
|
||||
|
||||
// Rellenar taxonomías
|
||||
const taxEl = detailEl.querySelector('.fp-geo-detail-taxonomies');
|
||||
if (taxEl) {
|
||||
taxEl.innerHTML = '';
|
||||
if (data.taxonomies) {
|
||||
for (const taxonomy in data.taxonomies) {
|
||||
data.taxonomies[taxonomy].forEach(function(term) {
|
||||
const tag = document.createElement('span');
|
||||
tag.className = 'fp-geo-detail-tax-tag';
|
||||
tag.style.cssText = term.color ? 'background-color: ' + term.color + ';' : '';
|
||||
|
||||
let html = '';
|
||||
if (term.icono) {
|
||||
html += '<img src="' + term.icono + '" alt="" class="fp-geo-detail-tax-icon">';
|
||||
}
|
||||
html += '<span>' + term.name + '</span>';
|
||||
tag.innerHTML = html;
|
||||
taxEl.appendChild(tag);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Thumbnail
|
||||
const thumbEl = detailEl.querySelector('.fp-geo-detail-thumbnail');
|
||||
if (thumbEl) {
|
||||
if (data.thumbnail) {
|
||||
thumbEl.innerHTML = '<img src="' + data.thumbnail + '" alt="' + data.title + '">';
|
||||
thumbEl.classList.add('has-image');
|
||||
} else {
|
||||
thumbEl.innerHTML = '';
|
||||
thumbEl.classList.remove('has-image');
|
||||
}
|
||||
}
|
||||
|
||||
// Título
|
||||
const titleEl = detailEl.querySelector('.fp-geo-detail-title');
|
||||
if (titleEl) {
|
||||
titleEl.textContent = data.title;
|
||||
}
|
||||
|
||||
// Excerpt
|
||||
const excerptEl = detailEl.querySelector('.fp-geo-detail-excerpt');
|
||||
if (excerptEl) {
|
||||
excerptEl.textContent = data.excerpt || '';
|
||||
}
|
||||
|
||||
// Ubicación
|
||||
const locationEl = detailEl.querySelector('.fp-geo-detail-location');
|
||||
if (locationEl) {
|
||||
const locationParts = [data.direccion, data.localidad].filter(Boolean);
|
||||
if (locationParts.length > 0) {
|
||||
locationEl.innerHTML = '<span>' + locationParts.join(', ') + '</span>';
|
||||
locationEl.style.display = 'flex';
|
||||
} else {
|
||||
locationEl.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
// Contacto
|
||||
const contactEl = detailEl.querySelector('.fp-geo-detail-contact');
|
||||
if (contactEl) {
|
||||
let contactHtml = '';
|
||||
|
||||
if (data.telefono) {
|
||||
contactHtml += '<div class="fp-geo-detail-contact-item">📞 <a href="tel:' + data.telefono.replace(/\s/g, '') + '">' + data.telefono + '</a></div>';
|
||||
}
|
||||
if (data.email) {
|
||||
contactHtml += '<div class="fp-geo-detail-contact-item">✉️ <a href="mailto:' + data.email + '">' + data.email + '</a></div>';
|
||||
}
|
||||
if (data.web) {
|
||||
contactHtml += '<div class="fp-geo-detail-contact-item">🌐 <a href="' + data.web + '" target="_blank">Sitio web</a></div>';
|
||||
}
|
||||
|
||||
contactEl.innerHTML = contactHtml;
|
||||
}
|
||||
|
||||
// Link - actualizar texto si está configurado
|
||||
const linkEl = detailEl.querySelector('.fp-geo-detail-link');
|
||||
if (linkEl) {
|
||||
linkEl.href = data.url;
|
||||
if (config.detailButtonText) {
|
||||
linkEl.textContent = config.detailButtonText;
|
||||
}
|
||||
}
|
||||
|
||||
// Footer - mostrar/ocultar según configuración
|
||||
const footerEl = detailEl.querySelector('.fp-geo-detail-footer');
|
||||
if (footerEl) {
|
||||
footerEl.style.display = config.showDetailButton ? 'block' : 'none';
|
||||
}
|
||||
|
||||
// Mostrar panel
|
||||
detailEl.classList.add('visible');
|
||||
if (overlayEl) {
|
||||
overlayEl.classList.add('visible');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ocultar panel de detalle
|
||||
*/
|
||||
function hideDetail(mapData) {
|
||||
const { config } = mapData;
|
||||
const detailEl = document.getElementById(config.mapId + '-detail');
|
||||
const overlayEl = document.getElementById(config.mapId + '-overlay');
|
||||
|
||||
if (detailEl) {
|
||||
detailEl.classList.remove('visible');
|
||||
}
|
||||
if (overlayEl) {
|
||||
overlayEl.classList.remove('visible');
|
||||
}
|
||||
}
|
||||
|
||||
// Exponer API pública
|
||||
window.FPGeoContent = {
|
||||
getMap: function(mapId) {
|
||||
return mapInstances[mapId];
|
||||
},
|
||||
refreshMarkers: function(mapId, markers) {
|
||||
const mapData = mapInstances[mapId];
|
||||
if (mapData) {
|
||||
addMarkers(mapData, markers);
|
||||
}
|
||||
},
|
||||
applyFilters: function(mapId) {
|
||||
const mapData = mapInstances[mapId];
|
||||
if (mapData) {
|
||||
applyFilters(mapData);
|
||||
}
|
||||
},
|
||||
fitToMarkers: function(mapId) {
|
||||
const mapData = mapInstances[mapId];
|
||||
if (mapData) {
|
||||
fitMapToMarkers(mapData);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user