Çlirim Kastrati
Çlirim Kastrati

Reputation: 83

Interactive map events in LeafletJS

I have created a world map with LeafletJS and GeoJSON, and I've added a click event for every country in the map, I got the name of the clicked country and displayed that name in an input field. It is required to click only two countries from the same map, I did it too, but the problem is that if I by mistake click a country I want to deselect that country and click(select) another one. When I deselect the country it should remove the name of that country from the input field too.

The UI looks like this:

enter image description here

The code for the form and the container for displaying the map:

<div id="mapid" style="margin-bottom: 30px;"></div>
        <form method="post">
            <div class="row" style="margin-bottom: 20px;">
                <div class="col-sm-12 col-md-6">
                    <div class="form-group">
                        <label for="first">First selected country</label>
                        <input type="text" id="first" class="form-control" name="country1" readonly>
                    </div>
                </div>
                <div class="col-sm-12 col-md-6">
                    <div class="form-group">
                        <label for="second">Second selected country</label>
                        <input type="text" id="second" class="form-control" name="country2" readonly>
                    </div>
                </div>
            </div>
            <label for="first">Message</label>
            <textarea id="" cols="" rows="10" class="form-control" name="message" style="margin-bottom: 20px;"></textarea>
            <input type="submit" value="SAVE" name="submit">
        </form>

And the code for the LeafletJS and GeoJSON:

<script>

var map = L.map('mapid').setView([0, 0], 1);

L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    attribution: '',
    id: 'mapbox/light-v9',
    tileSize: 512,
    zoomOffset: -1
}).addTo(map);

function getColor(d) {
    return  d > 1000 ? '#800026' :
            d > 500  ? '#BD0026' :
            d > 200  ? '#E31A1C' :
            d > 100  ? '#FC4E2A' :
            d > 50   ? '#FD8D3C' :
            d > 20   ? '#FEB24C' :
            d > 10   ? '#FED976' :
                        '#FFEDA0';
}

function style(feature) {
    return {
        weight: 2,
        opacity: 1,
        color: 'white',
        dashArray: '3',
        fillOpacity: 0.7,
        fillColor: getColor(feature.properties.ADMIN)
    };
}

var geojson;

function resetHighlight(e) {
    geojson.resetStyle(e.target);
    info.update();
}

var clickCounter = 0;

function zoomToFeature(e) {
    var clicked = false;
    if(clickCounter==0){
        document.getElementById('first').value=e.target.feature.properties.ADMIN
        clickCounter++;
        clicked = true;
        e.target.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });

        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            e.target.bringToFront();
        }
        if(clicked==true){
            e.target.on('click', function(){
                geojson.resetStyle(e.target);
                clicked = false;
                clickCounter = 0;
                document.getElementById('first').value="";
            })
        }
        if(clicked==false){
            e.target.on('click', function(){
                document.getElementById('first').value=e.target.feature.properties.ADMIN
                clickCounter++;
                clicked = true;
                e.target.setStyle({
                    weight: 5,
                    color: '#666',
                    dashArray: '',
                    fillOpacity: 0.7
                });

                if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
                    e.target.bringToFront();
                }
            })
        }
    }
    else if(clickCounter==1){

        document.getElementById('second').value=e.target.feature.properties.ADMIN
        clickCounter++;
        e.target.setStyle({
            weight: 5,
            color: '#666',
            dashArray: '',
            fillOpacity: 0.7
        });

        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
            e.target.bringToFront();
        }
        if(clicked==true){
            e.target.on('click', function(){
                geojson.resetStyle(e.target);
                clicked = false;
                clickCounter = 1;
                document.getElementById('second').value="";
            })
        }
        if(clicked==false){
            e.target.on('click', function(){
                document.getElementById('second').value=e.target.feature.properties.ADMIN
            clickCounter++;
            e.target.setStyle({
                weight: 5,
                color: '#666',
                dashArray: '',
                fillOpacity: 0.7
            });

            if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
                e.target.bringToFront();
            }
            })
        }
    }else{

    }
}

function onEachFeature(feature, layer) {
    layer.on({
        click: zoomToFeature
    });
}
var statesData = {
    "type": "FeatureCollection",
    "features": [{ "type": "Feature", "properties": { "ADMIN": "Aruba", "ISO_A3": "ABW", "ISO_A2": "AW" }, "geometry": { "type": "MultiPolygon",                "coordinates": [ [ [ [ -69.996937628999916, 12.577582098000036 ], [ -69.936390753999945, 12.531724351000051 ], [ -69.                                                   924672003999945, 12.519232489000046 ], [ -69.915760870999918, 12.497015692000076 ], [ -69.                                                  880197719999842, 12.453558661000045 ], [ -69.876820441999939, 12.427394924000097 ], [ -69.                                                  888091600999928, 12.417669989000046 ], [ -69.908802863999938, 12.417792059000107 ], [ -69.                                                  930531378999888, 12.425970770000035 ], [ -69.945139126999919, 12.44037506700009 ], [ -69.                                                   924672003999945, 12.44037506700009 ], [ -69.924672003999945, 12.447211005000014 ], [ -69.                                                   958566860999923, 12.463202216000099 ], [ -70.027658657999922, 12.522935289000088 ], [ -70.                                                  048085089999887, 12.531154690000079 ], [ -70.058094855999883, 12.537176825000088 ], [ -70.                                                  062408006999874, 12.546820380000057 ], [ -70.060373501999948, 12.556952216000113 ], [ -70.                                                  051096157999893, 12.574042059000064 ], [ -70.048736131999931, 12.583726304000024 ], [ -70.                                                  052642381999931, 12.600002346000053 ], [ -70.059641079999921, 12.614243882000054 ], [ -70.                                                  061105923999975, 12.625392971000068 ], [ -70.048736131999931, 12.632147528000104 ], [ -70.                                                  00715084499987, 12.5855166690001 ], [ -69.996937628999916, 12.577582098000036 ] ] ] ] } 
    },}

    geojson = L.geoJson(statesData, {
      style: style,
      onEachFeature: onEachFeature
    }).addTo(map);

Note that in the statesData array are datas for all countries, but the code is too large so I didn't added that part.

Upvotes: 0

Views: 707

Answers (1)

Falke Design
Falke Design

Reputation: 11338

Change your zoomToFeature function to:

function zoomToFeature(e) {
    var layer = e.target;
    var prop = layer.feature.properties.ADMIN;

    var first = document.getElementById('first');
    var second = document.getElementById('second');

    // can always set, because style will be reseted by "second" click
    layer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });
    if(first.value == prop){
        geojson.resetStyle(layer);
        first.value = "";
    }else if(second.value == prop){
        geojson.resetStyle(layer);
        second.value = "";
    }else if(first.value == ""){
        first.value = prop;
    }else if(second.value == ""){
        second.value = prop;
    }
    
    if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        e.target.bringToFront();
    }
}

Upvotes: 1

Related Questions