Search code examples
openlayers

Openlayers - create button to toggle select feature interaction, on and off, and clear the selection


I'm trying to create a button that performs select feature interaction, which when activated allows the selection and when deactivated restores the previous state eliminating the selection of the features. I wrote the interaction in 2 different ways but each has a critical issue. Can you tell me how to fix? Thank you.

1st way - the interaction activates correctly but does not deactivate

Console error when deactivate button: Cannot read properties of undefined (reading 'setActive')

var highlight = new ol.control.Toggle({
  html: '<i class=" fas fa-highlighter"></i>',
  title: 'Evidenzia',
  className: 'highlight-feature',
  onToggle: function(active) {      
    if (active) {       
        form_higlight.style.display = '';           
        var highlightStyle = new ol.style.Style({                           
            fill: new ol.style.Fill({
              color: 'rgba(0,153,255,0.4)'
            }),
            stroke: new ol.style.Stroke({
              color: 'rgba(0,153,255,1)',
              width: 0
            }),                         
        })
        var select = new ol.interaction.Select({
            style: highlightStyle
            });
        map.addInteraction(select);    
        select.setActive(true)
        });                 
    } else {        
        form_higlight.style.display = 'none';       
        map.removeInteraction(select);      
        select.setActive(false)          
        });                 
    }
  }
})
map.addControl(highlight)

2nd way - the interaction activates correctly, deactivates correctly, but the selection on the map is not eliminated

Console error when deactivate button: Uncaught TypeError: onHighlight is not a function

var doHighlight = false;
var highlight = new ol.control.Toggle({
  html: '<i class=" fas fa-highlighter"></i>',
  title: 'Evidenzia',
  className: 'highlight-feature',
  onToggle: function(active) {
    
    if (active) {
        form_higlight.style.display = '';
        var onHighlight = function(evt) {
            if (doHighlight) {
                    var highlightStyle = new ol.style.Style({                           
                        fill: new ol.style.Fill({
                          color: 'rgba(0,153,255,0.4)'
                        }),
                        stroke: new ol.style.Stroke({
                          color: 'rgba(0,153,255,1)',
                          width: 0
                        }),                         
                    })
                    var select = new ol.interaction.Select({
                        style: highlightStyle
                        });
                    map.addInteraction(select);
            }
            };
        doHighlight = true;
        map.on('singleclick', function(evt) {
            onHighlight(evt);
        });
        });         
    } else {        
        form_higlight.style.display = 'none';       
        doHighlight = false;        
        map.on('singleclick', function(evt) {
            if (onHighlight(evt)) {
                return;
            };
        });
        });             
    }
  }
})
map.addControl(highlight)

        

Solution

  • In your first method var select needs to be defined outside the function:

    var select;
    var highlight = new ol.control.Toggle({
      html: '<i class=" fas fa-highlighter"></i>',
      title: 'Evidenzia',
      className: 'highlight-feature',
      onToggle: function(active) {      
        if (active) {       
            form_higlight.style.display = '';           
            var highlightStyle = new ol.style.Style({                           
                fill: new ol.style.Fill({
                  color: 'rgba(0,153,255,0.4)'
                }),
                stroke: new ol.style.Stroke({
                  color: 'rgba(0,153,255,1)',
                  width: 0
                }),                         
            })
            select = new ol.interaction.Select({
                style: highlightStyle
                });
            map.addInteraction(select);    
            select.setActive(true)
            });                 
        } else {        
            form_higlight.style.display = 'none';       
            map.removeInteraction(select);      
            select.setActive(false)          
            });                 
        }
      }
    })
    map.addControl(highlight)
    

    There is similar issue with your onHighlight function being out of scope in the second attempt.