Filter Symbols by Text Input ​
Filter map features dynamically as the user types in a search box using setFilter().
Filter by Text Input ​
javascript
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', (e) => {
const query = e.target.value.trim().toLowerCase();
if (!query) {
map.setFilter('my-layer', null); // show all
return;
}
// Filter: feature name contains the query string
map.setFilter('my-layer', [
'in',
query,
['downcase', ['get', 'name']]
]);
});Complete Example ​
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<link href="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.css" rel="stylesheet" />
<script src="https://cdn.mapmetrics-atlas.net/versions/latest/mapmetrics-gl.js"></script>
<style>#map { height: 500px; width: 100%; }</style>
</head>
<body>
<input id="search" type="text" placeholder="Search..." style="padding:8px;margin-bottom:8px;width:300px;" />
<div id="map"></div>
<script>
const map = new mapmetricsgl.Map({ container: 'map', style: '<StyleFile_URL_with_Token>', center: [10, 50], zoom: 3 });
map.on('load', () => {
map.addSource('cities', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [
{ type: 'Feature', properties: { name: 'Paris' }, geometry: { type: 'Point', coordinates: [2.349902, 48.852966] } },
{ type: 'Feature', properties: { name: 'London' }, geometry: { type: 'Point', coordinates: [-0.1276, 51.5074] } },
{ type: 'Feature', properties: { name: 'Berlin' }, geometry: { type: 'Point', coordinates: [13.405, 52.52] } },
]
}
});
map.addLayer({ id: 'cities-layer', type: 'circle', source: 'cities', paint: { 'circle-radius': 9, 'circle-color': '#3b82f6' } });
});
document.getElementById('search').addEventListener('input', (e) => {
const q = e.target.value.toLowerCase();
map.setFilter('cities-layer', q ? ['in', q, ['downcase', ['get', 'name']]] : null);
});
</script>
</body>
</html>jsx
import React, { useEffect, useRef, useState } from 'react';
import mapmetricsgl from '@mapmetrics/mapmetrics-gl';
import '@mapmetrics/mapmetrics-gl/dist/mapmetrics-gl.css';
const citiesData = {
type: 'FeatureCollection',
features: [
{ type: 'Feature', properties: { name: 'Paris' }, geometry: { type: 'Point', coordinates: [2.349902, 48.852966] } },
{ type: 'Feature', properties: { name: 'London' }, geometry: { type: 'Point', coordinates: [-0.1276, 51.5074] } },
{ type: 'Feature', properties: { name: 'Berlin' }, geometry: { type: 'Point', coordinates: [13.405, 52.52] } },
]
};
const FilterByText = () => {
const mapContainer = useRef(null);
const map = useRef(null);
const [query, setQuery] = useState('');
useEffect(() => {
if (map.current) return;
map.current = new mapmetricsgl.Map({ container: mapContainer.current, style: '<StyleFile_URL_with_Token>', center: [10, 50], zoom: 3 });
map.current.on('load', () => {
map.current.addSource('cities', { type: 'geojson', data: citiesData });
map.current.addLayer({ id: 'cities-layer', type: 'circle', source: 'cities', paint: { 'circle-radius': 9, 'circle-color': '#3b82f6' } });
});
return () => { map.current?.remove(); map.current = null; };
}, []);
const handleSearch = (e) => {
const q = e.target.value.toLowerCase();
setQuery(q);
if (!map.current) return;
map.current.setFilter('cities-layer', q ? ['in', q, ['downcase', ['get', 'name']]] : null);
};
return (
<div>
<input type="text" value={query} onChange={handleSearch} placeholder="Search cities..." style={{ padding: '8px', marginBottom: '8px', width: '300px' }} />
<div ref={mapContainer} style={{ height: '500px', width: '100%' }} />
</div>
);
};
export default FilterByText;For more information, visit the MapMetrics GitHub repository.