Custom Control with Text Input - No Focus

3,698 views
Skip to first unread message

Markus Straub

unread,
Nov 4, 2012, 4:02:34 PM11/4/12
to leafl...@googlegroups.com
Hi, I would like to create a custom control with a text input field. My first approach:

var textControl = L.control();
textControl.onAdd = function (map) {
    var div = L.DomUtil.create('div', 'leaflet-control');
    div.innerHTML += '<input type="textbox" />';
    return div;
};
rkGlobal.map.addControl(textControl);


The input field is visible, but after clicking into it it is not focused (no blinking cursor, typing does not work). I noticed, that right-clicking and then typing works, but this is of course not feasible.

My guess is that leaflet catches the left-click and it never reaches the input field. Is there a way to circumvent this - or does anybody know the exact reason why this approach does not work?

Thanks!

Andrew M.

unread,
Nov 7, 2012, 11:07:26 PM11/7/12
to leafl...@googlegroups.com
Hi Markus,

I ran into a similar problem today and agree that it's probably an issue with the map catching the left-click before it reaches the input.  What I've found to work is to temporarily turn on / off the map's dragging interaction option.  You can do this via map.dragging.enable() and map.dragging.disable() (see http://leafletjs.com/reference.html, near the top).  Since it appears that the map is only blocking left mouse click events, the most logical way to approach this seems to be to just use onmouseover and onmouseout to call functions to adjust the map settings as needed.  I've tried attaching them to both a) the input tags themselves, and b) the entire control area and have demonstrated a quick write-up of both below.  Please let me know if you find a better way to do it.  I'd love to know.

Thanks and good luck,
Andrew

//Create map
var map = L.map('map');

//Create control
myControl = L.control({position: 'bottomright'});
myControl.onAdd = function(map) {
            this._div = L.DomUtil.create('div', 'myControl');
            this._div.innerHTML = '<input type="text" value="A" />' +
                                  '<input type="text" value="B" />' +
                                  '<input type="text" value="C" />'
            return this._div;
}
myControl.addTo(map);

//Functions to either disable (onmouseover) or enable (onmouseout) the map's dragging
function controlEnter(e) {
    map.dragging.disable();
}
function controlLeave() {
    map.dragging.enable();
}

//Quick application to all input tags
///*
var inputTags = document.getElementsByTagName("input")
for (var i = 0; i < inputTags.length; i++) {
    inputTags[i].onmouseover = controlEnter;
    inputTags[i].onmouseout = controlLeave;
}
//*/

// --- OR ---

//Quick application of event handlers to overall control
/*
document.getElementsByClassName("myControl")[0].onmouseover = controlEnter;
document.getElementsByClassName("myControl")[0].onmouseout = controlLeave;
//*/

Guillaume de Boyer

unread,
Nov 12, 2012, 12:25:03 AM11/12/12
to leafl...@googlegroups.com
Hi Andrew,

I have got the same problem and your solution works pretty well. Thank you :)

Markus Straub

unread,
Nov 28, 2012, 2:05:14 PM11/28/12
to leafl...@googlegroups.com
Hi Andrew,

thanks a lot, your code works like a charm. Leaflet-search also deals with this problem and I wanted to dig into the code but I have not enough time right now. The code is hosted at Gibhub: https://github.com/stefanocudini/leaflet-search

Best,
Markus

Chris Erickson

unread,
Dec 18, 2014, 4:04:21 PM12/18/14
to leafl...@googlegroups.com
I just came across this thread when encountering the same problem, and after digging into the leaflet-search example, found the magic sauce:

L.DomEvent.disableClickPropagation(inputControl)

Calling that on the input makes it work correctly....

Reply all
Reply to author
Forward
Message has been deleted
0 new messages