From ae3ba699407b88e7c049819df69e49690924f41e Mon Sep 17 00:00:00 2001 From: Stefan Forsgren Date: Fri, 27 Sep 2024 13:03:55 +0200 Subject: [PATCH 1/3] WIP search-popup-configurable --- src/controls/search.js | 54 +++++++-- src/featureinfo.js | 251 ++++++++++++++++++++-------------------- src/selectionmanager.js | 31 +++-- 3 files changed, 194 insertions(+), 142 deletions(-) diff --git a/src/controls/search.js b/src/controls/search.js index a98e752ac..ca359f49c 100644 --- a/src/controls/search.js +++ b/src/controls/search.js @@ -47,7 +47,8 @@ const Search = function Search(options = {}) { queryParameterName = 'q', autocompletePlacement, searchlistOptions = {}, - queryType + queryType, + supressDialog, } = options; const searchlistPlacement = searchlistOptions.placement; @@ -70,18 +71,33 @@ const Search = function Search(options = {}) { viewer.removeOverlays(overlay); } } - + /** + * Displays the search result in an overlay (featureInfo's infoWindow-setting is ignored). Does not require that the features are from a layer. + * @param {any} features Array of features to display, but ony the first is actually displayed + * @param {any} objTitle Titel in the popup + * @param {any} content The html-content to be displayed the popup. + */ function showFeatureInfo(features, objTitle, content) { const obj = {}; obj.feature = features[0]; obj.title = objTitle; obj.content = content; clear(); - featureInfo.render([obj], 'overlay', getCenter(features[0].getGeometry()), { ignorePan: true }); + // Call featureInfo to display search result in overlay. This does not obey featureInfo's 'infoWindow'-setting. + // Can't use featureInfo.ShowFeatureInfo here as that requires a layer to format content + // TODO: lägg på ignore popupoption + featureInfo.render([obj], 'overlay', getCenter(features[0].getGeometry()), { ignorePan: true, supressDialog }); viewer.zoomToExtent(features[0].getGeometry(), maxZoomLevel); } + /** + * Shows an overlay with selected search result when there is no feature, + * just a coordinate and preformatted content. + * @param {any} data search result + * @param {any} coord where to show the popup + */ function showOverlay(data, coord) { + // TODO: skall denna sätta en plupp om man supressar popupen? clear(); const newPopup = popup(`#${viewer.getId()}`); overlay = new Overlay({ @@ -91,6 +107,7 @@ const Search = function Search(options = {}) { map.addOverlay(overlay); overlay.setPosition(coord); + // Take content from search result attribute named same as search attribute. const content = data[name]; newPopup.setContent({ content, @@ -124,39 +141,62 @@ const Search = function Search(options = {}) { let content; let coord; if (layerNameAttribute && idAttribute) { + // This is option 1 above + // The search endpoint has only returned a layer name and a feature id. We must get the actual feature to get the geometry and + // let featureInfo format the popup content. const source = viewer.getMapSource(); const projCode = viewer.getProjectionCode(); const proj = viewer.getProjection(); layer = viewer.getLayer(data[layerNameAttribute]); id = data[idAttribute]; + // Fetch the feature from map server in case it is not fetched already by the layers source (in case of BBOX) + // or the layer is WMS, in which case source holds no features. getFeature() has a strnge behaviour to try to fetch features from + // feom a "shadow"-wfs layer by just assuming there is an wfs endpoint in the same location as WMS layer (works for GeoServer) getFeature(id, layer, source, projCode, proj) .then((res) => { let featureWkt; let coordWkt; if (res.length > 0) { const featLayerName = layer.get('name'); - featureInfo.showFeatureInfo({ feature: res, layerName: featLayerName }, { maxZoomLevel }); + // TODO: lägg på ignore popupoption + featureInfo.showFeatureInfo({ feature: res, layerName: featLayerName }, { maxZoomLevel, supressDialog }); } else if (geometryAttribute) { - // Fallback if no geometry in response + // Fallback if the id was not present in the layer. Try to create feature from search endpoint result + // FIXME: this case is not documented and indicates some configuration error featureWkt = mapUtils.wktToFeature(data[geometryAttribute], projectionCode); coordWkt = featureWkt.getGeometry().getCoordinates(); showOverlay(data, coordWkt); } }); } else if (geometryAttribute && layerName) { + // This should probably be option 2 above, but the description is incorrect and it does not work. + // Feature is returned as a WKT and content is formatted using the layer's attributes configuration + // too bad the feature won't have any attributes as WKT only contains geometry. + // FIXME: according to description, feature should be fetched from server, not parsed from response and geometryattribute should not be necessary + // Maybe the intention was to receive a complete feature in geometryAttribute. feature = mapUtils.wktToFeature(data[geometryAttribute], projectionCode); - featureInfo.showFeatureInfo({ feature: [feature], layerName }, { maxZoomLevel }); + // TODO: lägg på ignore popupoption även om det inte funkar + featureInfo.showFeatureInfo({ feature: [feature], layerName }, { maxZoomLevel, supressDialog }); } else if (titleAttribute && contentAttribute && geometryAttribute) { + // This is option 3 above + // Search endpoint provides popup title, geometry as WKT and preformatted content. feature = mapUtils.wktToFeature(data[geometryAttribute], projectionCode); // Make sure the response is wrapped in a html element content = utils.createElement('div', data[contentAttribute]); showFeatureInfo([feature], data[titleAttribute], content); } else if (geometryAttribute && title) { + // This is option 4 + // Search endpoint provides geometry as WKT, content is taken from same attribute that is configured as search attribute. + // FIXME: it should be documented that the content should/can be provided in the search result. feature = mapUtils.wktToFeature(data[geometryAttribute], projectionCode); content = utils.createElement('div', data[name]); showFeatureInfo([feature], title, content); } else if (easting && northing && title) { + // This is option 5. + // An overlay is displayed at the position specified by the attributes in the search result. + // content is taken from same attribute that is configured as search attribute + // FIXME: it should be documented that the content should/can be provided in the search result. coord = [data[easting], data[northing]]; showOverlay(data, coord); } else { @@ -392,7 +432,7 @@ const Search = function Search(options = {}) { .then((res) => { if (res.length > 0) { const featureLayerName = layer.get('name'); - featureInfo.showFeatureInfo({ feature: res, layerName: featureLayerName }, { maxZoomLevel }); + featureInfo.showFeatureInfo({ feature: res, layerName: featureLayerName }, { maxZoomLevel, supressDialog }); } }); }); diff --git a/src/featureinfo.js b/src/featureinfo.js index 8051add86..79bb7659c 100644 --- a/src/featureinfo.js +++ b/src/featureinfo.js @@ -312,137 +312,134 @@ const Featureinfo = function Featureinfo(options = {}) { * @param {any} coordinate * @param {bool} ignorePan true if overlay should not be panned into view */ - const doRender = function doRender(identifyItems, target, coordinate, ignorePan) { - const map = viewer.getMap(); - - items = identifyItems; + const doRender = function doRender(identifyItems, target, coordinate, ignorePan, supressDialog) { clear(false); - // FIXME: variable is overwritten in next row - let content = items.map((i) => i.content).join(''); - content = '
'; - switch (target) { - case 'overlay': - { - popup = Popup(`#${viewer.getId()}`, { closeCb: onInfoClosed }); - popup.setContent({ - content, - title: getTitle(items[0]) - }); - const contentDiv = document.getElementById('o-identify-carousel'); - const carouselIds = []; - items.forEach((item) => { - carouselIds.push(item.feature.ol_uid); - if (item.content instanceof Element) { - contentDiv.appendChild(item.content); - } else { - contentDiv.innerHTML = item.content; - } - }); - popup.setVisibility(true); - initCarousel('#o-identify-carousel'); - const firstFeature = items[0].feature; - const geometry = firstFeature.getGeometry(); - const origostyle = firstFeature.get('origostyle'); - const clone = firstFeature.clone(); - clone.setId(firstFeature.getId()); - // FIXME: should be layer name, not feature name - clone.layerName = firstFeature.name; - selectionLayer.clearAndAdd( - clone, - selectionStyles[geometry.getType()] - ); - selectionLayer.setSourceLayer(items[0].layer); - const coord = geometry.getType() === 'Point' ? geometry.getCoordinates() : coordinate; - carouselIds.forEach((carouselId) => { - let targetElement; - const elements = document.getElementsByClassName(`o-image-carousel${carouselId}`); - Array.from(elements).forEach(element => { - if (!element.closest('.glide__slide--clone')) { - targetElement = element; + items = identifyItems; + if (target === 'infowindow') { + // TODO: första gången visas ingen markering + if (items.length === 1) { + selectionManager.addOrHighlightItem(items[0], {supressDialog}); + } else if (items.length > 1) { + selectionManager.addItems(items, { supressDialog }); + } + } else { + const map = viewer.getMap(); + + + + // Add the first feature to selection layer. + // Only one is added, the others are added when the carousel changes. + const firstFeature = items[0].feature; + const geometry = firstFeature.getGeometry(); + const clone = firstFeature.clone(); + clone.setId(firstFeature.getId()); + selectionLayer.clearAndAdd( + clone, + selectionStyles[geometry.getType()] + ); + selectionLayer.setSourceLayer(items[0].layer); + + // Create the popup/side bar + + if (!supressDialog) { + + const content = '
'; + switch (target) { + case 'overlay': + { + popup = Popup(`#${viewer.getId()}`, { closeCb: onInfoClosed }); + popup.setContent({ + content, + title: getTitle(items[0]) + }); + const contentDiv = document.getElementById('o-identify-carousel'); + const carouselIds = []; + items.forEach((item) => { + carouselIds.push(item.feature.ol_uid); + if (item.content instanceof Element) { + contentDiv.appendChild(item.content); + } else { + contentDiv.innerHTML = item.content; + } + }); + popup.setVisibility(true); + initCarousel('#o-identify-carousel'); + const origostyle = firstFeature.get('origostyle'); + + const coord = geometry.getType() === 'Point' ? geometry.getCoordinates() : coordinate; + carouselIds.forEach((carouselId) => { + let targetElement; + const elements = document.getElementsByClassName(`o-image-carousel${carouselId}`); + Array.from(elements).forEach(element => { + if (!element.closest('.glide__slide--clone')) { + targetElement = element; + } + }); + const imageCarouselEl = document.getElementsByClassName(`o-image-carousel${carouselId}`); + if (imageCarouselEl.length > 0) { + initImageCarousel(`#o-image-carousel${carouselId}`, `.o-image-content${carouselId}`, carouselId, targetElement); + } + }); + const popupEl = popup.getEl(); + const popupHeight = document.querySelector('.o-popup').offsetHeight + 10; + popupEl.style.height = `${popupHeight}px`; + const overlayOptions = { element: popupEl, positioning: 'bottom-center' }; + if (!ignorePan) { + overlayOptions.autoPan = { + margin: 55, + animation: { + duration: 500 + } + }; + } + if (items[0].layer && items[0].layer.get('styleName')) { + const styleName = items[0].layer.get('styleName'); + const itemStyle = viewer.getStyle(styleName); + if (itemStyle && itemStyle[0] && itemStyle[0][0] && itemStyle[0][0].overlayOptions) { + Object.assign(overlayOptions, itemStyle[0][0].overlayOptions); + } + } + if (origostyle && origostyle.overlayOptions) { + Object.assign(overlayOptions, origostyle.overlayOptions); + } + if (overlayOptions.positioning) { + popupEl.classList.add(`popup-${overlayOptions.positioning}`); + } + overlay = new Overlay(overlayOptions); + map.addOverlay(overlay); + overlay.setPosition(coord); + break; } - }); - const imageCarouselEl = document.getElementsByClassName(`o-image-carousel${carouselId}`); - if (imageCarouselEl.length > 0) { - initImageCarousel(`#o-image-carousel${carouselId}`, `.o-image-content${carouselId}`, carouselId, targetElement); - } - }); - const popupEl = popup.getEl(); - const popupHeight = document.querySelector('.o-popup').offsetHeight + 10; - popupEl.style.height = `${popupHeight}px`; - const overlayOptions = { element: popupEl, positioning: 'bottom-center' }; - if (!ignorePan) { - overlayOptions.autoPan = { - margin: 55, - animation: { - duration: 500 + case 'sidebar': + { + sidebar.setContent({ + content, + title: getTitle(items[0]) + }); + const contentDiv = document.getElementById('o-identify-carousel'); + items.forEach((item) => { + if (item.content instanceof Element) { + contentDiv.appendChild(item.content); + } else { + contentDiv.innerHTML = item.content; + } + }); + sidebar.setVisibility(true); + + initCarousel('#o-identify-carousel'); + break; + } + + default: + { + break; } - }; - } - if (items[0].layer && items[0].layer.get('styleName')) { - const styleName = items[0].layer.get('styleName'); - const itemStyle = viewer.getStyle(styleName); - if (itemStyle && itemStyle[0] && itemStyle[0][0] && itemStyle[0][0].overlayOptions) { - Object.assign(overlayOptions, itemStyle[0][0].overlayOptions); - } - } - if (origostyle && origostyle.overlayOptions) { - Object.assign(overlayOptions, origostyle.overlayOptions); } - if (overlayOptions.positioning) { - popupEl.classList.add(`popup-${overlayOptions.positioning}`); + const modalLinks = document.getElementsByClassName('o-identify-link-modal'); + for (let i = 0; i < modalLinks.length; i += 1) { + addLinkListener(modalLinks[i]); } - overlay = new Overlay(overlayOptions); - map.addOverlay(overlay); - overlay.setPosition(coord); - break; } - case 'sidebar': - { - sidebar.setContent({ - content, - title: getTitle(items[0]) - }); - const contentDiv = document.getElementById('o-identify-carousel'); - items.forEach((item) => { - if (item.content instanceof Element) { - contentDiv.appendChild(item.content); - } else { - contentDiv.innerHTML = item.content; - } - }); - sidebar.setVisibility(true); - const firstFeature = items[0].feature; - const geometry = firstFeature.getGeometry(); - const clone = firstFeature.clone(); - clone.setId(firstFeature.getId()); - // FIXME: should be layer name - clone.layerName = firstFeature.name; - selectionLayer.clearAndAdd( - clone, - selectionStyles[geometry.getType()] - ); - selectionLayer.setSourceLayer(items[0].layer); - initCarousel('#o-identify-carousel'); - break; - } - case 'infowindow': - { - if (items.length === 1) { - selectionManager.addOrHighlightItem(items[0]); - } else if (items.length > 1) { - selectionManager.addItems(items); - } - break; - } - default: - { - break; - } - } - - const modalLinks = document.getElementsByClassName('o-identify-link-modal'); - for (let i = 0; i < modalLinks.length; i += 1) { - addLinkListener(modalLinks[i]); } // Don't send event for infowindow. Infowindow will send an event that triggers sending the event later. if (target === 'overlay' || target === 'sidebar') { @@ -459,7 +456,7 @@ const Featureinfo = function Featureinfo(options = {}) { * @param {any} opts Additional options. Supported options are : ignorePan, disable auto pan to popup overlay. */ const render = function render(identifyItems, target, coordinate, opts = {}) { - doRender(identifyItems, target, coordinate, opts.ignorePan); + doRender(identifyItems, target, coordinate, opts.ignorePan, opts.supressDialog); }; /** * Renders the selectedItems after adding async content. Not actually defined as async as it is part of a sync call chain, @@ -481,7 +478,7 @@ const Featureinfo = function Featureinfo(options = {}) { alert('Kunde inte hämta relaterade objekt. En del fält från relaterade objekt kommer att vara tomma.'); }) .then(() => { - doRender(identifyItems, target, coordinate, opts.ignorePan); + doRender(identifyItems, target, coordinate, opts.ignorePan, opts.supressDialog); }) .catch(err => console.log(err)); } diff --git a/src/selectionmanager.js b/src/selectionmanager.js index ce3f34b08..4a9adc833 100644 --- a/src/selectionmanager.js +++ b/src/selectionmanager.js @@ -27,7 +27,7 @@ const Selectionmanager = function Selectionmanager(options = {}) { let infowindow; /** The selectionmanager component itself */ let component; - + /** Keeps track of highlighted features. Stores pointers to the actual features. */ let highlightedFeatures = []; @@ -81,10 +81,20 @@ const Selectionmanager = function Selectionmanager(options = {}) { } } - function addItems(items) { + /** + * Adds an array of items to selection. + * @param {SelectedItem []} items Array of items to add + * @param {object} opts Object with options + * @param {boolean} opts.supressDialog If true the dialog is not opened, only selection in map is made + */ + function addItems(items, opts = {}) { + const supressDialog = opts.supressDialog; items.forEach((item) => { addItem(item); }); + if (!supressDialog) { + infowindow.show(); + } } /** Helper that refreshes all urvallayers. Typically called after highlightning or symbology has changed */ @@ -137,8 +147,14 @@ const Selectionmanager = function Selectionmanager(options = {}) { infowindow.highlightListElement(featureId); infowindow.scrollListElementToView(featureId); } - - function addOrHighlightItem(item) { + /** + * Adds one item and highlights it. If it already is in the list it is just highlighted. + * @param {SelectedItem} item Item to add + * @param {object} opts Object with options + * @param {boolean} opts.supressDialog If true the dialog is not opened, only selection in map is made + */ + function addOrHighlightItem(item, opts = {}) { + const supressDialog = opts.supressDialog; if (alreadyExists(item)) { if (toggleSelectOnClick) { removeItems([item]); @@ -149,6 +165,9 @@ const Selectionmanager = function Selectionmanager(options = {}) { } else { // add selectedItems.push(item); + if (!supressDialog) { + infowindow.show(); + } if (selectedItems.getLength() === 1) { highlightAndExpandItem(item); } @@ -296,10 +315,6 @@ const Selectionmanager = function Selectionmanager(options = {}) { urval.get(selectionGroup).addFeature(item.getFeature()); infowindow.createListElement(item); - if (isInfowindow) { - infowindow.show(); - } - const sum = urval.get(selectionGroup).getFeatures().length; infowindow.updateUrvalElementText(selectionGroup, selectionGroupTitle, sum); const aggregationstring = calculateGroupAggregations(selectionGroup); From de33f5b7bb426a22d045ea090ca715d526368329 Mon Sep 17 00:00:00 2001 From: Stefan Forsgren Date: Wed, 20 Nov 2024 09:50:47 +0100 Subject: [PATCH 2/3] Lint --- src/controls/search.js | 2 +- src/featureinfo.js | 164 ++++++++++++++++++++-------------------- src/selectionmanager.js | 2 +- 3 files changed, 82 insertions(+), 86 deletions(-) diff --git a/src/controls/search.js b/src/controls/search.js index ca359f49c..f6dc66e1d 100644 --- a/src/controls/search.js +++ b/src/controls/search.js @@ -48,7 +48,7 @@ const Search = function Search(options = {}) { autocompletePlacement, searchlistOptions = {}, queryType, - supressDialog, + supressDialog } = options; const searchlistPlacement = searchlistOptions.placement; diff --git a/src/featureinfo.js b/src/featureinfo.js index 79bb7659c..6df990416 100644 --- a/src/featureinfo.js +++ b/src/featureinfo.js @@ -316,17 +316,15 @@ const Featureinfo = function Featureinfo(options = {}) { clear(false); items = identifyItems; if (target === 'infowindow') { - // TODO: första gången visas ingen markering if (items.length === 1) { - selectionManager.addOrHighlightItem(items[0], {supressDialog}); + selectionManager.addOrHighlightItem(items[0], { supressDialog }); } else if (items.length > 1) { selectionManager.addItems(items, { supressDialog }); } } else { + // Overlay or sidebar goes here const map = viewer.getMap(); - - // Add the first feature to selection layer. // Only one is added, the others are added when the carousel changes. const firstFeature = items[0].feature; @@ -340,100 +338,98 @@ const Featureinfo = function Featureinfo(options = {}) { selectionLayer.setSourceLayer(items[0].layer); // Create the popup/side bar - if (!supressDialog) { - const content = '
'; switch (target) { case 'overlay': - { - popup = Popup(`#${viewer.getId()}`, { closeCb: onInfoClosed }); - popup.setContent({ - content, - title: getTitle(items[0]) - }); - const contentDiv = document.getElementById('o-identify-carousel'); - const carouselIds = []; - items.forEach((item) => { - carouselIds.push(item.feature.ol_uid); - if (item.content instanceof Element) { - contentDiv.appendChild(item.content); - } else { - contentDiv.innerHTML = item.content; - } - }); - popup.setVisibility(true); - initCarousel('#o-identify-carousel'); - const origostyle = firstFeature.get('origostyle'); - - const coord = geometry.getType() === 'Point' ? geometry.getCoordinates() : coordinate; - carouselIds.forEach((carouselId) => { - let targetElement; - const elements = document.getElementsByClassName(`o-image-carousel${carouselId}`); - Array.from(elements).forEach(element => { - if (!element.closest('.glide__slide--clone')) { - targetElement = element; - } - }); - const imageCarouselEl = document.getElementsByClassName(`o-image-carousel${carouselId}`); - if (imageCarouselEl.length > 0) { - initImageCarousel(`#o-image-carousel${carouselId}`, `.o-image-content${carouselId}`, carouselId, targetElement); + { + popup = Popup(`#${viewer.getId()}`, { closeCb: onInfoClosed }); + popup.setContent({ + content, + title: getTitle(items[0]) + }); + const contentDiv = document.getElementById('o-identify-carousel'); + const carouselIds = []; + items.forEach((item) => { + carouselIds.push(item.feature.ol_uid); + if (item.content instanceof Element) { + contentDiv.appendChild(item.content); + } else { + contentDiv.innerHTML = item.content; + } + }); + popup.setVisibility(true); + initCarousel('#o-identify-carousel'); + const origostyle = firstFeature.get('origostyle'); + + const coord = geometry.getType() === 'Point' ? geometry.getCoordinates() : coordinate; + carouselIds.forEach((carouselId) => { + let targetElement; + const elements = document.getElementsByClassName(`o-image-carousel${carouselId}`); + Array.from(elements).forEach(element => { + if (!element.closest('.glide__slide--clone')) { + targetElement = element; } }); - const popupEl = popup.getEl(); - const popupHeight = document.querySelector('.o-popup').offsetHeight + 10; - popupEl.style.height = `${popupHeight}px`; - const overlayOptions = { element: popupEl, positioning: 'bottom-center' }; - if (!ignorePan) { - overlayOptions.autoPan = { - margin: 55, - animation: { - duration: 500 - } - }; + const imageCarouselEl = document.getElementsByClassName(`o-image-carousel${carouselId}`); + if (imageCarouselEl.length > 0) { + initImageCarousel(`#o-image-carousel${carouselId}`, `.o-image-content${carouselId}`, carouselId, targetElement); } - if (items[0].layer && items[0].layer.get('styleName')) { - const styleName = items[0].layer.get('styleName'); - const itemStyle = viewer.getStyle(styleName); - if (itemStyle && itemStyle[0] && itemStyle[0][0] && itemStyle[0][0].overlayOptions) { - Object.assign(overlayOptions, itemStyle[0][0].overlayOptions); + }); + const popupEl = popup.getEl(); + const popupHeight = document.querySelector('.o-popup').offsetHeight + 10; + popupEl.style.height = `${popupHeight}px`; + const overlayOptions = { element: popupEl, positioning: 'bottom-center' }; + if (!ignorePan) { + overlayOptions.autoPan = { + margin: 55, + animation: { + duration: 500 } + }; + } + if (items[0].layer && items[0].layer.get('styleName')) { + const styleName = items[0].layer.get('styleName'); + const itemStyle = viewer.getStyle(styleName); + if (itemStyle && itemStyle[0] && itemStyle[0][0] && itemStyle[0][0].overlayOptions) { + Object.assign(overlayOptions, itemStyle[0][0].overlayOptions); } - if (origostyle && origostyle.overlayOptions) { - Object.assign(overlayOptions, origostyle.overlayOptions); - } - if (overlayOptions.positioning) { - popupEl.classList.add(`popup-${overlayOptions.positioning}`); - } - overlay = new Overlay(overlayOptions); - map.addOverlay(overlay); - overlay.setPosition(coord); - break; } + if (origostyle && origostyle.overlayOptions) { + Object.assign(overlayOptions, origostyle.overlayOptions); + } + if (overlayOptions.positioning) { + popupEl.classList.add(`popup-${overlayOptions.positioning}`); + } + overlay = new Overlay(overlayOptions); + map.addOverlay(overlay); + overlay.setPosition(coord); + break; + } case 'sidebar': - { - sidebar.setContent({ - content, - title: getTitle(items[0]) - }); - const contentDiv = document.getElementById('o-identify-carousel'); - items.forEach((item) => { - if (item.content instanceof Element) { - contentDiv.appendChild(item.content); - } else { - contentDiv.innerHTML = item.content; - } - }); - sidebar.setVisibility(true); + { + sidebar.setContent({ + content, + title: getTitle(items[0]) + }); + const contentDiv = document.getElementById('o-identify-carousel'); + items.forEach((item) => { + if (item.content instanceof Element) { + contentDiv.appendChild(item.content); + } else { + contentDiv.innerHTML = item.content; + } + }); + sidebar.setVisibility(true); - initCarousel('#o-identify-carousel'); - break; - } + initCarousel('#o-identify-carousel'); + break; + } default: - { - break; - } + { + break; + } } const modalLinks = document.getElementsByClassName('o-identify-link-modal'); for (let i = 0; i < modalLinks.length; i += 1) { diff --git a/src/selectionmanager.js b/src/selectionmanager.js index 14098e8eb..db57900e8 100644 --- a/src/selectionmanager.js +++ b/src/selectionmanager.js @@ -27,7 +27,7 @@ const Selectionmanager = function Selectionmanager(options = {}) { let infowindow; /** The selectionmanager component itself */ let component; - + /** Keeps track of highlighted features. Stores pointers to the actual features. */ let highlightedFeatures = []; From d15cac38870c062c9f97c6b374aac61801e05d8f Mon Sep 17 00:00:00 2001 From: Stefan Forsgren Date: Wed, 20 Nov 2024 10:04:38 +0100 Subject: [PATCH 3/3] Fixed spelling and removed todo:s --- src/controls/search.js | 14 +++++--------- src/featureinfo.js | 12 ++++++------ src/selectionmanager.js | 12 ++++++------ 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/controls/search.js b/src/controls/search.js index f6dc66e1d..d841b4e6c 100644 --- a/src/controls/search.js +++ b/src/controls/search.js @@ -48,7 +48,7 @@ const Search = function Search(options = {}) { autocompletePlacement, searchlistOptions = {}, queryType, - supressDialog + suppressDialog } = options; const searchlistPlacement = searchlistOptions.placement; @@ -85,8 +85,7 @@ const Search = function Search(options = {}) { clear(); // Call featureInfo to display search result in overlay. This does not obey featureInfo's 'infoWindow'-setting. // Can't use featureInfo.ShowFeatureInfo here as that requires a layer to format content - // TODO: lägg på ignore popupoption - featureInfo.render([obj], 'overlay', getCenter(features[0].getGeometry()), { ignorePan: true, supressDialog }); + featureInfo.render([obj], 'overlay', getCenter(features[0].getGeometry()), { ignorePan: true, suppressDialog }); viewer.zoomToExtent(features[0].getGeometry(), maxZoomLevel); } @@ -97,7 +96,6 @@ const Search = function Search(options = {}) { * @param {any} coord where to show the popup */ function showOverlay(data, coord) { - // TODO: skall denna sätta en plupp om man supressar popupen? clear(); const newPopup = popup(`#${viewer.getId()}`); overlay = new Overlay({ @@ -158,8 +156,7 @@ const Search = function Search(options = {}) { let coordWkt; if (res.length > 0) { const featLayerName = layer.get('name'); - // TODO: lägg på ignore popupoption - featureInfo.showFeatureInfo({ feature: res, layerName: featLayerName }, { maxZoomLevel, supressDialog }); + featureInfo.showFeatureInfo({ feature: res, layerName: featLayerName }, { maxZoomLevel, suppressDialog }); } else if (geometryAttribute) { // Fallback if the id was not present in the layer. Try to create feature from search endpoint result // FIXME: this case is not documented and indicates some configuration error @@ -175,8 +172,7 @@ const Search = function Search(options = {}) { // FIXME: according to description, feature should be fetched from server, not parsed from response and geometryattribute should not be necessary // Maybe the intention was to receive a complete feature in geometryAttribute. feature = mapUtils.wktToFeature(data[geometryAttribute], projectionCode); - // TODO: lägg på ignore popupoption även om det inte funkar - featureInfo.showFeatureInfo({ feature: [feature], layerName }, { maxZoomLevel, supressDialog }); + featureInfo.showFeatureInfo({ feature: [feature], layerName }, { maxZoomLevel, suppressDialog }); } else if (titleAttribute && contentAttribute && geometryAttribute) { // This is option 3 above // Search endpoint provides popup title, geometry as WKT and preformatted content. @@ -432,7 +428,7 @@ const Search = function Search(options = {}) { .then((res) => { if (res.length > 0) { const featureLayerName = layer.get('name'); - featureInfo.showFeatureInfo({ feature: res, layerName: featureLayerName }, { maxZoomLevel, supressDialog }); + featureInfo.showFeatureInfo({ feature: res, layerName: featureLayerName }, { maxZoomLevel, suppressDialog }); } }); }); diff --git a/src/featureinfo.js b/src/featureinfo.js index 6df990416..57d13e3ed 100644 --- a/src/featureinfo.js +++ b/src/featureinfo.js @@ -312,14 +312,14 @@ const Featureinfo = function Featureinfo(options = {}) { * @param {any} coordinate * @param {bool} ignorePan true if overlay should not be panned into view */ - const doRender = function doRender(identifyItems, target, coordinate, ignorePan, supressDialog) { + const doRender = function doRender(identifyItems, target, coordinate, ignorePan, suppressDialog) { clear(false); items = identifyItems; if (target === 'infowindow') { if (items.length === 1) { - selectionManager.addOrHighlightItem(items[0], { supressDialog }); + selectionManager.addOrHighlightItem(items[0], { suppressDialog }); } else if (items.length > 1) { - selectionManager.addItems(items, { supressDialog }); + selectionManager.addItems(items, { suppressDialog }); } } else { // Overlay or sidebar goes here @@ -338,7 +338,7 @@ const Featureinfo = function Featureinfo(options = {}) { selectionLayer.setSourceLayer(items[0].layer); // Create the popup/side bar - if (!supressDialog) { + if (!suppressDialog) { const content = '
'; switch (target) { case 'overlay': @@ -452,7 +452,7 @@ const Featureinfo = function Featureinfo(options = {}) { * @param {any} opts Additional options. Supported options are : ignorePan, disable auto pan to popup overlay. */ const render = function render(identifyItems, target, coordinate, opts = {}) { - doRender(identifyItems, target, coordinate, opts.ignorePan, opts.supressDialog); + doRender(identifyItems, target, coordinate, opts.ignorePan, opts.suppressDialog); }; /** * Renders the selectedItems after adding async content. Not actually defined as async as it is part of a sync call chain, @@ -474,7 +474,7 @@ const Featureinfo = function Featureinfo(options = {}) { alert('Kunde inte hämta relaterade objekt. En del fält från relaterade objekt kommer att vara tomma.'); }) .then(() => { - doRender(identifyItems, target, coordinate, opts.ignorePan, opts.supressDialog); + doRender(identifyItems, target, coordinate, opts.ignorePan, opts.suppressDialog); }) .catch(err => console.log(err)); } diff --git a/src/selectionmanager.js b/src/selectionmanager.js index db57900e8..3d1323ce6 100644 --- a/src/selectionmanager.js +++ b/src/selectionmanager.js @@ -84,14 +84,14 @@ const Selectionmanager = function Selectionmanager(options = {}) { * Adds an array of items to selection. * @param {SelectedItem []} items Array of items to add * @param {object} opts Object with options - * @param {boolean} opts.supressDialog If true the dialog is not opened, only selection in map is made + * @param {boolean} opts.suppressDialog If true the dialog is not opened, only selection in map is made */ function addItems(items, opts = {}) { - const supressDialog = opts.supressDialog; + const suppressDialog = opts.suppressDialog; items.forEach((item) => { addItem(item); }); - if (!supressDialog) { + if (!suppressDialog) { infowindow.show(); } } @@ -150,10 +150,10 @@ const Selectionmanager = function Selectionmanager(options = {}) { * Adds one item and highlights it. If it already is in the list it is just highlighted. * @param {SelectedItem} item Item to add * @param {object} opts Object with options - * @param {boolean} opts.supressDialog If true the dialog is not opened, only selection in map is made + * @param {boolean} opts.suppressDialog If true the dialog is not opened, only selection in map is made */ function addOrHighlightItem(item, opts = {}) { - const supressDialog = opts.supressDialog; + const suppressDialog = opts.suppressDialog; if (alreadyExists(item)) { if (toggleSelectOnClick) { removeItems([item]); @@ -164,7 +164,7 @@ const Selectionmanager = function Selectionmanager(options = {}) { } else { // add selectedItems.push(item); - if (!supressDialog) { + if (!suppressDialog) { infowindow.show(); } if (selectedItems.getLength() === 1) {