Сейчас узнаем, какой подарок выпадет именно Вам
Крутите колесо
Как сделать таб-список адресов для карты в Тильда
Санкт-Петербург
РИВ ГОШ в ТЦ «Жемчужная Плаза»
59.849831, 30.144982
Петергофское шоссе, 51 А
8 (812) 777-77-77
Пн-Вс 10:00 - 22:00
РИВ ГОШ в универмаге «Московский»
59.846830, 30.322516
Московский просп., 220
8 (812) 777-77-77
Пн-Вс 10:00 - 22:00
РИВ ГОШ в универмаге Пассаж
59.934758, 30.334275
Невский пр., 48
8 (812) 777-77-77
Пн-Вс 10:00 - 22:00
Москва
РИВ ГОШ на проспекте Мира
55.845855, 37.662093
просп. Мира, 211, корп. 2 этаж 1
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
РИВ ГОШ в ТЦ Мега Белая дача
55.653299, 37.844217

1-й Покровский пр., 5, Котельники этаж 1

8 (905) 777-77-77

Пн-Вс 10:00 - 22:00

РИВ ГОШ на Цветном бульваре
55.771145, 37.620177
Цветной бул., 15, стр. 1 этаж 1
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Золотое Яблоко в ТРК "Метрополис"
55.823216, 37.497468
Ленинградское шоссе, 16А, стр. 4
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Золотое Яблоко в ТРК "Европолис"
55.845855, 37.662093
пр-т Мира, 211, корп. 2
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Адлер
РИВ ГОШ в City Plaza
43.427671, 39.926853
Кирова, 58 1 этаж
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Казань
РИВ ГОШ в ТЦ "Авеню"
55.820617, 49.095517
пр. Ибрагимова, 56а
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Калуга
РИВ ГОШ в МФЦ "На Рылеева"
54.514885, 36.249986
ул. Кирова, 20
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Красноярск
РИВ ГОШ в ТРК "Планета"
56.050918, 92.904378
ул. 9 мая, 77
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Сочи
РИВ ГОШ в МТРК "МореМолл"
43.606254, 39.732314
ул. Новая Заря, 7
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Новосибирск
Золотое Яблоко
55.054526, 82.914851
Красный проспект, 98
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Екатеринбург
Золотое Яблоко в ТЦ "Bolshoy"
56.836973, 60.623157
ул. Малышева, д. 71
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Ростов-на-Дону
Золотое Яблоко в ТЦ "Горизонт"
47.261482, 39.719343
проспект Михаила Нагибина, 32Д/2
8 (905) 777-77-77
Пн-Вс 10:00 - 22:00
Наши
магазины
Найдите ближайший магазин и посетите нас лично

Как сделать таб-список адресов для карты в Тильда

1
Для наполнения карты используем блоки TS140N (задаём им класс uc-map-point )
2
В заголовок шапки блока пишем название города (см. рис. 1)
Для каждого города свой блок TS140N
3
Описание точки проводим в контенте блока для каждой карточки (см. рис. 2)
  • Заголовок - это название точки
  • Описание - координаты
  • Изображение - это иконка для карты
  • Текст - сюда пишем уже телефон, время работы, адрес и другое
Примерный такое должно получиться (см. рис. 3)
4
Вставили код на страницу в блок Т123
Сам блок и будет являться картой
Библиотека для примера
<div class="map-container">
    <div id="mapyandex"></div>
</div>

<script src="https://api-maps.yandex.ru/2.1/?lang=ru_RU" type="text/javascript"></script>

<script>
const CONFIG = {
    MAP_ZOOM: 12,
    SCROLL_SPEED: 500,
    MOBILE_BREAKPOINT: 960
};

const state = {
    coordinates: [],
    currentMap: null,
    geoCollection: null,
    points: [],
    selectedIndex: 0,
    isMapReady: false
};

const DOM = {
    mapElement: document.getElementById('mapyandex'),
    mapContainer: document.querySelector('.map-container'),
    tagsInput: null,
    adressMain: null
};

function createUI() {
    const adressWrapper = document.createElement('div');
    adressWrapper.className = 'adress-wrapper-wrp';
    adressWrapper.innerHTML = `
        <div class="adress-wrapper-input t-text">
            <input type="text" class="t-input tags" placeholder="Город" id="citySearch">
            <div class="autocomplete-list" id="autocompleteList"></div>
        </div>
        <div class="adress-wrapper-main t-text" id="adressList"></div>
    `;
    
    DOM.mapElement.after(adressWrapper);
    
    DOM.tagsInput = document.getElementById('citySearch');
    DOM.adressMain = document.getElementById('adressList');
    DOM.autocompleteList = document.getElementById('autocompleteList');
}

class Autocomplete {
    constructor(input, source) {
        this.input = input;
        this.source = source;
        this.list = document.getElementById('autocompleteList');
        this.selectedIndex = -1;
        this.isOpen = false;
        
        this.input.addEventListener('input', () => this.handleInput());
        this.input.addEventListener('focus', () => this.handleFocus());
        this.input.addEventListener('blur', () => this.handleBlur());
        this.input.addEventListener('keydown', (e) => this.handleKeydown(e));
        
        document.addEventListener('click', (e) => {
            if (!this.list.contains(e.target) && e.target !== this.input) {
                this.hideList();
            }
        });
    }
    
    handleInput() {
        const value = this.input.value.toLowerCase().trim();
        const filtered = this.source.filter(item => 
            item.toLowerCase().includes(value)
        );
        this.showList(filtered);
    }
    
    handleFocus() {
        if (this.input.value.trim()) {
            this.handleInput();
        } else {
            this.showList(this.source);
        }
    }
    
    handleBlur() {
        setTimeout(() => this.hideList(), 200);
    }
    
    handleKeydown(e) {
        const items = this.list.querySelectorAll('.autocomplete-item');
        if (items.length === 0) return;
        
        switch(e.key) {
            case 'ArrowDown':
                e.preventDefault();
                this.selectedIndex = Math.min(this.selectedIndex + 1, items.length - 1);
                this.updateSelection(items);
                break;
            case 'ArrowUp':
                e.preventDefault();
                this.selectedIndex = Math.max(this.selectedIndex - 1, -1);
                this.updateSelection(items);
                break;
            case 'Enter':
                e.preventDefault();
                if (this.selectedIndex >= 0) {
                    items[this.selectedIndex].click();
                }
                break;
            case 'Escape':
                this.hideList();
                break;
        }
    }
    
    updateSelection(items) {
        items.forEach((item, index) => {
            item.classList.toggle('active', index === this.selectedIndex);
        });
        
        if (this.selectedIndex >= 0) {
            items[this.selectedIndex].scrollIntoView({ block: 'nearest' });
        }
    }
    
    showList(items) {
        if (items.length === 0) {
            this.hideList();
            return;
        }
        
        this.list.innerHTML = items.map((item, index) => `
            <div class="autocomplete-item" data-index="${index}" data-value="${item}">
                ${item}
            </div>
        `).join('');
        
        this.list.style.display = 'block';
        this.isOpen = true;
        this.selectedIndex = -1;
        
        this.list.querySelectorAll('.autocomplete-item').forEach(el => {
            el.addEventListener('mousedown', (e) => {
                e.preventDefault();
            });
            el.addEventListener('click', () => {
                this.input.value = el.dataset.value;
                this.hideList();
                this.input.focus();
                handleCitySelect(state.points);
            });
        });
    }
    
    hideList() {
        this.list.style.display = 'none';
        this.isOpen = false;
        this.selectedIndex = -1;
    }
}

function getMapPoints() {
    const points = document.querySelectorAll('.uc-map-point');
    const result = [];
    
    points.forEach(point => {
        const title = point.querySelector('.t-section__title')?.textContent?.trim() || '';
        const items = point.querySelectorAll('.t-slds__item');
        const pointData = { title, items: [] };
        
        items.forEach(item => {
            const name = item.querySelector('.t-heading')?.innerHTML || '';
            const coordText = item.querySelector('.t-descr')?.textContent || '';
            const coords = coordText.split(',').map(c => c.trim());
            const image = item.querySelector('.t-bgimg')?.getAttribute('data-original') || '';
            const description = item.querySelector('.t-text')?.innerHTML || '';
            
            pointData.items.push({
                name,
                coords,
                image,
                description,
                balloonContent: `${name}<br>${description}`
            });
        });
        
        result.push(pointData);
    });
    
    return result;
}

function handleCitySelect(points) {
    const city = DOM.tagsInput.value.trim();
    const selectedPoint = points.find(p => p.title === city);
    
    if (selectedPoint) {
        fillList(selectedPoint);
    }
}

function fillList(pointData) {
    DOM.adressMain.innerHTML = '';
    DOM.mapElement.innerHTML = '';
    state.coordinates = [];
    state.isMapReady = false;
    
    const adressItems = pointData.items.map((item, index) => {
        const coordLine = [
            item.coords[0],
            item.coords[1],
            item.name,
            item.image,
            item.balloonContent,
            item.description
        ];
        state.coordinates.push(coordLine);
        
        return `
            <div class="adress-item" data-tab-num="${index}">
                <div class="adress-item-inner-wrap">
                    <div class="adress-title">${item.name}</div>
                    <div class="adress-descr">${item.description}</div>
                </div>
            </div>
        `;
    });
    
    DOM.adressMain.innerHTML = adressItems.join('');
    DOM.tagsInput.value = pointData.title;
    
    document.querySelectorAll('.adress-item').forEach(item => {
        item.addEventListener('click', handleItemClick);
    });
    
    const firstItem = document.querySelector('.adress-item[data-tab-num="0"]');
    if (firstItem) {
        firstItem.classList.add('activepoint');
        state.selectedIndex = 0;
    }
    
    createMap();
}

function handleItemClick(e) {
    const item = e.currentTarget;
    const pointNum = parseInt(item.dataset.tabNum);
    
    document.querySelectorAll('.adress-item').forEach(el => el.classList.remove('activepoint'));
    item.classList.add('activepoint');
    state.selectedIndex = pointNum;
    
    if (state.coordinates[pointNum]) {
        changePoint(pointNum);
    }
    
    if (window.innerWidth < CONFIG.MOBILE_BREAKPOINT) {
        const mapYmaps = document.querySelector('#mapyandex ymaps');
        if (mapYmaps) {
            const top = mapYmaps.getBoundingClientRect().top + window.pageYOffset - 50;
            window.scrollTo({ top, behavior: 'smooth' });
        }
    }
}

function createMap() {
    if (state.coordinates.length === 0) return;
    
    ymaps.ready(() => {
        if (state.currentMap) {
            state.currentMap.destroy();
            state.currentMap = null;
        }
        
        const centerCoords = [state.coordinates[0][0], state.coordinates[0][1]];
        
        state.currentMap = new ymaps.Map("mapyandex", {
            center: centerCoords,
            zoom: CONFIG.MAP_ZOOM,
            controls: []
        }, {
            searchControlProvider: 'yandex#search',
            suppressMapOpenBlock: true
        });
        
        state.currentMap.controls.add('zoomControl', {
            position: {
                right: 20,
                top: 150
            },
            size: 'small'
        });
        
        state.geoCollection = new ymaps.GeoObjectCollection(null, {
            preset: 'islands#yellowIcon'
        });
        
        state.coordinates.forEach((coord, index) => {
            const placemark = new ymaps.Placemark(
                [coord[0], coord[1]],
                {
                    hintContent: coord[2],
                    balloonContent: coord[4],
                },
                {
                    iconLayout: 'default#imageWithContent',
                    openBalloonOnClick: false,
                    openHintOnHover: true,
                    hintTimeout: 300,
                    iconImageHref: coord[3],
                    iconImageSize: [50, 50],
                    iconImageOffset: [-25, -25],
                    iconContentOffset: [25, 25],
                }
            );
            
            placemark.properties.set('index', index);
            placemark.properties.set('coordIndex', index);
            state.geoCollection.add(placemark);
        });
        
        state.currentMap.geoObjects.add(state.geoCollection);
        
        state.geoCollection.options.set({
            hintLayout: 'default#hint',
            hintOffset: [0, -20],
            hintTimeout: 200,
            hintHideTimeout: 1000
        });
        
        state.geoCollection.events.add('click', function(e) {
            const target = e.get('target');
            const coords = target.geometry._coordinates;
            const index = target.properties.get('coordIndex');
            
            if (index !== undefined && state.coordinates[index]) {
                state.currentMap.balloon.open(
                    coords, 
                    state.coordinates[index][4]
                );
                
                const item = document.querySelector(`.adress-item[data-tab-num="${index}"]`);
                if (item) {
                    document.querySelectorAll('.adress-item').forEach(el => el.classList.remove('activepoint'));
                    item.classList.add('activepoint');
                    state.selectedIndex = index;
                    
                    const container = DOM.adressMain;
                    const itemOffset = item.offsetTop;
                    const containerScrollTop = container.scrollTop;
                    const containerOffset = container.offsetTop;
                    
                    container.scrollTo({
                        top: containerScrollTop - containerOffset + itemOffset - 20,
                        behavior: 'smooth'
                    });
                }
            }
        });
        
        state.isMapReady = true;
        
        setTimeout(() => {
            if (state.currentMap) {
                state.currentMap.container.fitToViewport();
            }
        }, 100);
    });
}

function changePoint(index) {
    if (!state.currentMap || !state.coordinates[index]) return;
    
    const coords = [state.coordinates[index][0], state.coordinates[index][1]];
    
    state.currentMap.balloon.open(coords, state.coordinates[index][4]);
    
    setTimeout(() => {
        state.currentMap.panTo([+coords[0], +coords[1]], { 
            delay: 2500,
            flying: true
        });
    }, 200);
}

let resizeTimeout;

function handleResize() {
    clearTimeout(resizeTimeout);
    resizeTimeout = setTimeout(() => {
        if (state.currentMap && state.isMapReady) {
            state.currentMap.container.fitToViewport();
        }
    }, 200);
}

document.addEventListener('DOMContentLoaded', function() {
    createUI();
    state.points = getMapPoints();
    
    if (state.points.length > 0) {
        DOM.tagsInput.value = state.points[0].title;
        
        const availableTags = state.points.map(p => p.title);
        new Autocomplete(DOM.tagsInput, availableTags);
        
        fillList(state.points[0]);
        
        DOM.tagsInput.addEventListener('change', () => {
            handleCitySelect(state.points);
        });
    }
    
    window.addEventListener('resize', handleResize);
});

function openBalloonByIndex(index) {
    if (state.currentMap && state.coordinates[index]) {
        const coords = [state.coordinates[index][0], state.coordinates[index][1]];
        state.currentMap.balloon.open(coords, state.coordinates[index][4]);
    }
}

function getCurrentMap() {
    return state.currentMap;
}

function getCoordinates() {
    return state.coordinates;
}

window.openBalloonByIndex = openBalloonByIndex;
window.getCurrentMap = getCurrentMap;
window.getCoordinates = getCoordinates;
</script>

<style>

.uc-map-point {
    display: none;
}

.adress-wrapper-input {
    position: relative;
    padding: 20px;
    display: flex;
    gap: 8px;
}

.adress-wrapper-input input {
    border: 1px solid #e0e0e0;
    height: 45px;
    border-radius: 10px;
    flex-grow:1;
    font-size: 16px;
    padding: 0 10px;
    box-sizing: border-box;
    outline: none;
}

.adress-wrapper-input input:focus {
    border-color: #9a8a6e;
    box-shadow: 0 0 0 2px rgba(154, 138, 110, 0.2);
}

.autocomplete-list {
    display: none;
    position: absolute;
    top: calc(100% - 20px);
    left: 10px;
    right: 10px;
    background: #ffffff;
    border: 1px solid #cccccb;
    border-radius: 5px;
    max-height: 300px;
    overflow-y: auto;
    z-index: 9999999;
    margin-top: 4px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.autocomplete-item {
    padding: 10px 15px;
    cursor: pointer;
    transition: background 0.2s ease;
    color: #5d5d5d;
}

.autocomplete-item:hover,
.autocomplete-item.active {
    background: #f5f0eb;
    color: #000000;
}

.map-container {
    height: 600px;
    position: relative;
    display: grid;
    grid-template-columns: 1fr 380px;
    border-radius: 15px;
    overflow: hidden;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04), 0 8px 32px rgba(0, 0, 0, 0.06), 0 24px 60px rgba(0, 0, 0, 0.04);
}

#mapyandex {
    padding: 0;
    margin: 0;
    position: relative;
    min-height: 400px;
}

.adress-wrapper-wrp {
    height: inherit;
    background-color: #fff;
}

.adress-wrapper-main {
    top: 0;
    right: 0;
    z-index: 99;
    height: inherit;
    overflow: auto;
    max-height: 535px;
    color: #000;
}

.adress-wrapper-main::-webkit-scrollbar {
    width: 6px;
    height: 6px;
    background: #f0f0f0;
}

.adress-wrapper-main::-webkit-scrollbar-thumb {
    background: #a7a7a7;
    border-radius: 10px;
}

.adress-wrapper-main::-webkit-scrollbar-thumb:hover {
    background: #8a8a8a;
}

.adress-wrapper-main::-webkit-scrollbar-track {
    background: #f0f0f0;
}

.adress-wrapper-main {
    scrollbar-width: thin;
    scrollbar-color: #a7a7a7 #f0f0f0;
}

.autocomplete-list::-webkit-scrollbar {
    width: 6px;
    height: 6px;
    background: #f0f0f0;
    border-radius: 0 5px 5px 0;
}

.autocomplete-list::-webkit-scrollbar-thumb {
    background: #a7a7a7;
    border-radius: 10px;
}

.autocomplete-list::-webkit-scrollbar-thumb:hover {
    background: #8a8a8a;
}

.autocomplete-list::-webkit-scrollbar-track {
    background: #f0f0f0;
    border-radius: 0 5px 5px 0;
}

.autocomplete-list {
    scrollbar-width: thin;
    scrollbar-color: #a7a7a7 #f0f0f0;
}

.adress-item {
    background-color: #fff;
    padding: 12px 20px;
    line-height: 1.5;
    cursor: pointer;
    border-bottom: 1px solid #d7d7d7;
    transition: all 0.3s ease;
}

.adress-item:hover {
    background: #f9f7f5;
}

.adress-item > div {
    pointer-events: none;
}

.adress-item.activepoint {
    background: rgba(154, 138, 110, 0.07);
    box-shadow: inset 3px 0 0 0 #c4a86a;
}

.adress-title {
    font-weight: 500;
    margin-bottom: 4px;
}

.adress-title strong {
    color: #9a8a6e;
    font-weight: 400;
    font-size: 16px !important;
}

.adress-descr {
    font-size: 14px;
    color: #666;
}

.adress-descr > * {
    font-size: 14px !important;
}

ymaps[class$="-balloon__content"] strong {
    padding: 5px 0;
}

@media screen and (max-width: 960px) {
    .map-container {
        grid-template-columns: 1fr;
        height: max-content;
    }

    .adress-wrapper-main {
        position: static;
        width: 100%;
        height: 370px;
        margin-bottom: 20px;
    }

    .adress-title > div {
        font-size: 16px !important;
    }

    .adress-descr,
    .adress-descr > * {
        font-size: 13px !important;
    }

    #mapyandex {
        height: 400px;
        margin-top: 0px;
    }

    .adress-item {
        box-shadow: inset 0 0 0 1px #ededed;
    }
    
    .autocomplete-list {
        max-height: 200px;
    }
}

.adress-item-inner-wrap {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

@media screen and (max-width: 480px) {
    #mapyandex {
        height: 300px;
    }
    
    .adress-wrapper-main {
        height: 250px;
    }
}
</style>
Made on
Tilda