[GIS] ExtJS custom popup on OpenLayers 3 (and the terrifying event propagation problem :O)

ext-jsopenlayerspopup

I'm trying to make work a custom popup with a datagrid. The popup visually displays correctly, but the problem is how events propagate.

The popup is an ext panel (with a datagrid) who is rendered on a div. This div is set as the element of the ol.Overlay added to the map.

The event propagation problem

For the event propagation, the ol.Overlay have the 'stopEvent' option. If it is setted to true, the click events doesn't work on the popup. You can select elements on the grid, or select the 'Save' button but to press the button (or edit the grid element) you have to select the element and then press enter on the keyboard.

If 'stopEvent' option is setted to false, the popup events fires ok, but if you double-click the popup the map is zoomed, if you drag the popup the map is dragged too, etc…

You can view and test the code here:

http://jsfiddle.net/j8fLmju8/

Sorry I couldn't make the styles work on the fiddle it should look like this:

enter image description here

Another trouble with the fiddle (that works ok on my app) is when stopEvent is setted to true, if you select an element on the grid and press enter it always edit the first value, just ignore that.

Finally

I don't know what should be the next step. Try to use stopEvent=false and do something to priorize the panel events over the ol.Overlay? Use stopEvent=true and try to stop the map events when clicked on the panel? i don't even know if I can do anithing of this. Another option?

PD: I've tried the GeoExt 3 popup but it doesn't fit to my needs.

Best Answer

Finally I've found an answer. 'mouseover' and 'mouseout' events can be overridden if you access the DOM element of your Ext control. The next code disables all interactions on mouseover and keeps an array with the disabled interactions, on mouseout the interactions are enabled again.

var popup = Ext.create('My.Custom.Control', { ... });
var disabledInteractions = [];

popup.el.on('mouseover', function(event) {
        if (!event.within(popup.el, true)){

            var interactions = [];
            map.getInteractions().forEach(function(interaction) {
                // Here you can filter the interactions you don't want
                interactions.push(interaction);
            }, this);

            interactions.forEach(function(interaction) {
                disabledInteractions.push(interaction);
                map.removeInteraction(interaction);
            });
        }
    },
    popup
);

popup.el.on('mouseout', function(event) {
        if (!event.within(popup.el, true)){
            disabledInteractions.forEach(function(interaction){
                map.addInteraction(interaction);
            });
            disabledInteractions  = [];
        }
    },
    popup
);

NOTE: Don't forget to reenable inteactions on pupup close button or on close event.