I have a map rendering with Polygons on a Vector layer set up as features. I set up the features so they fire off a function when the feature is selected and this works fine. The issue I'm having is when I try to allow users to select multiple features using a box. This causes the function to fire for each feature that is selected. I understand why this is, but what I really need is to have a function that fires once all of the features are selected so I can run a function using all selected features instead of having it run once for each. Here is my selectFeature code:

                        var selectCtrl = new OpenLayers.Control.SelectFeature(layerVector, {
                            clickout: true,
                            onSelect: onFeatureSelect,
                            onUnselect: onFeatureUnselect,
                            box: true

It looks like there's away to attach Handlers to Boxes but so far I've been unsuccessful. Also, I'm afraid that if the function runs after the box selection is finished, it might not be getting the full list of selectedFeatures.

Any help would be GREATLY appreciated. Thanks


You could modify selectBox method of SelectFeature control:

OpenLayers.Control.SelectFeature.prototype.selectBox = function(position) {
if (position instanceof OpenLayers.Bounds) {
    var minXY = this.map.getLonLatFromPixel(
        new OpenLayers.Pixel(position.left, position.bottom)
    var maxXY = this.map.getLonLatFromPixel(
        new OpenLayers.Pixel(position.right, position.top)
    var bounds = new OpenLayers.Bounds(
        minXY.lon, minXY.lat, maxXY.lon, maxXY.lat

    // if multiple is false, first deselect currently selected features
    if (!this.multipleSelect()) {

    // because we're using a box, we consider we want multiple selection
    var prevMultiple = this.multiple;
    this.multiple = true;
    var layers = this.layers || [this.layer];
    var layer;
    var selectedFeatures = []; // <-- Modification of original function (1/3)
    for(var l=0; l<layers.length; ++l) {
        layer = layers[l];
        for(var i=0, len = layer.features.length; i<len; ++i) {
            var feature = layer.features[i];
            // check if the feature is displayed
            if (!feature.getVisibility()) {

            if (this.geometryTypes == null || OpenLayers.Util.indexOf(
                this.geometryTypes, feature.geometry.CLASS_NAME) > -1) {
                    if (bounds.toGeometry().intersects(feature.geometry)) {
                        if (OpenLayers.Util.indexOf(layer.selectedFeatures, feature) == -1) {
                            selectedFeatures.push(feature); // <-- Modification of original function (2/3)
    onFeatureSelect(selectedFeatures); // <-- Modification of original function (3/3)
    this.multiple = prevMultiple;

Live example

| improve this answer | |
  • Brilliant. Really excellent stuff, thanks. One small issue I'm now running into is that I'd also like to allow the user to click an individual feature. So, I can't add an onSelect function to the SelectFeature control or else it will run as each feature is selected and once more if a box was used. Your code worked great in returning all of the features, but I'm unsure how to allow for a single click. – Munzilla Jan 10 '12 at 15:29
  • Actually nevermind, I was able to do it by modifying OpenLayers.Control.SelectFeature.prototype.clickFeature similar to what you did with selectBox. This was enlightening, thanks a lot. – Munzilla Jan 10 '12 at 15:40
  • Quick question...if I wanted this box to only appear when shift is pressed, is there an easy way to do this? My users aren't happy about losing the ability to navigate with the mouse. – Munzilla Jan 10 '12 at 16:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.