Take the 2-minute tour ×

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

share|improve this question

1 Answer 1

up vote 3 down vote accepted

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

share|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


