https://www.website.ro/harta这是使用leaflet.js和https://github.com/stefanocudini/leaflet-search,但我只能搜索单个位置。
https://www.website.ro/public/ajax?q=electri
如果我搜索";电气;它有3个位置,我想在点击回车时显示它们,而不是显示";未找到";。
stackoverflow已经在谷歌上搜索过了,但没有找到类似的答案/问题。
这可以通过仔细使用传单搜索提供的选项来完成。首先,让我们创建一个数组来保存潜在的结果,并创建一个featureLayer来渲染显示的任何结果:
const results = [];
var resultsLayer = L.featureGroup();
现在,我们可以将buildTip
选项覆盖为一个函数,该函数几乎完成了默认情况下已经完成的操作,但也将结果推送到一个数组:
var controlSearch = new L.Control.Search({
...options,
// hijack buildtip function, push results to array
buildTip: (text, loc) => {
results.push(loc); // <---- crucial line here
// the rest of this is lifted from the source code almost exactly
// so as to keep the same behavior when clicking on an option
const tip = L.DomUtil.create("div");
tip.innerHTML = text;
L.DomEvent.disableClickPropagation(tip)
.on(tip, "click", L.DomEvent.stop, controlSearch)
.on(
tip,
"click",
function (e) {
controlSearch._input.value = text;
controlSearch._handleAutoresize();
controlSearch._input.focus();
controlSearch._hideTooltip();
controlSearch._handleSubmit();
},
controlSearch
);
return tip;
},
// only move to the location if there are not multiple results
moveToLocation: results.length
? () => {}
: L.Control.Search._defaultMoveToLocation
});
现在,我们在搜索的输入中添加一个事件侦听器,如果用户按下回车键,并且有多个结果,则推送到results
数组中的结果将作为标记添加到resultsLayer
中,并添加到映射中:
inputEl.addEventListener("keypress", function (e) {
if (e.key === "Enter" && results.length) {
markersLayer.remove();
results.forEach((result) => {
const marker = L.marker(result);
resultsLayer.addLayer(marker);
});
map.fitBounds(resultsLayer.getBounds());
}
});
工作代码沙箱
请注意,这可能需要一些清理工作(即在新的或空的搜索中清空数组(,或者在搜索为空时读取完整的数据集,等等,但这应该足以让您开始。
编辑-完整项目信息
你在评论中问我们如何获得项目的全部细节并将其放入弹出窗口。通过阅读传单搜索的文档和源代码,似乎没有任何地方的代码"捕捉"到整个数据对象。buildTip
函数实际上只需要一个项中的两条数据-要在工具提示中显示的文本和它所指的位置。有很多关于将源数据保存在缓存中的TODO
,但它们仍然是待办事项。
我要做的是使用结果中返回的title
和loc
来过滤原始数据,并在原始数据中找到相应的项:
const getFullItem = (title, loc) => {
return data.find((item) => item.title === title && loc.equals(item.loc));
};
我们还可以创建一个通用函数来为所有制造商和结果构建弹出文本,因此弹出窗口都是一致的:
const buildPopupText = (item) => {
return `
<h4>Title: ${item.title}</h4>
<p>Phone: ${item.telefon}</p>
<p>more stuff from ${item.whatever}</p>
`;
};
当我们点击回车键并通过results
进行映射时,我们将使用结果来获得原始项目:
inputEl.addEventListener("keypress", function (e) {
if (e.key === "Enter" && results.length) {
results.forEach((result) => {
const originalItem = getFullItem(result.text, result.loc);
const marker = L.marker(result.loc);
marker.bindPopup(buildPopupText(originalItem));
resultsLayer.addLayer(marker);
});
map.fitBounds(resultsLayer.getBounds());
}
});
因此,现在结果弹出窗口从originalItem
构建了一个弹出窗口,它具有您需要的所有属性。