Search code examples
jvectormap

Jvectormap place only one new marker on a pre selected region


i'm currently working on a script for the user to select a place on a map for a travel webapp, i'm also a newbie and have no working knowledge on javascript, I am developing the webapp on python -flask, and since the map works on JS im currently stuck.

What I need is that after the user selects a country on the map, then they should place a marker within that selected country, I looked at he example on jvectormap webpage on markers and am working off that, but that example allows for several markers whereas I need to have just one marker to be placed, after the country is selected, right now I can have the country selected but as you click that country a marker is placed, so I would rather need that the marker is allowed if the region is selected, there is the onRegionSelected attribute but I haven't been able to figure out how to use the isSelected attribute for that function so I would appreciate your help very much with this.

Also after this is done I need to pass the coordinates of this marker to a form onto a database, so if this is possible could you help me out with this as well? Im using wtforms but i dont know how to access variables from javascript, I would need the values from the marker to store them in a db via form,

thank you in advance!

code:



    <div id="world-map" style="width: 800px; height: 600px"></div>

    <script>
      $(function(){
            var map,
                markerIndex = 0,
                markersCoords = {};

            map = new jvm.Map({
                map: 'world_mill',
                markerStyle: {
                  initial: {
                    fill: 'red'
                  }
                },
                hoverColor: '#FCEF06',
                hover: {
                    stroke: 'black',
                    "stroke-width": 2,
                    fill:'#FCEF06'
                },

                regionsSelectable: true,
                regionsSelectableOne: true, 
                regionStyle: {
                    fill:'black',
                    selected: {
                        fill: 'red'
                    }
                }, 
                container: $('#world-map'),

                onMarkerTipShow: function(e, label, code){
                  map.tip.text(markersCoords[code].lat.toFixed(2)+', '+markersCoords[code].lng.toFixed(2));
                },
                onMarkerClick: function(e, code){
                  map.removeMarkers([code]);
                  map.tip.hide();
                }


            });

            map.container.click(function(e){
                var latLng = map.pointToLatLng(
                        e.pageX - map.container.offset().left,
                        e.pageY - map.container.offset().top
                    ),
                    targetCls = $(e.target).attr('class');

                if (latLng && (!targetCls || (targetCls && $(e.target).attr('class').indexOf('jvectormap-marker') === -1))) {
                  markersCoords[markerIndex] = latLng;
                  map.addMarker(markerIndex, {latLng: [latLng.lat, latLng.lng]});
                  markerIndex += 1;
                }
            });
          });
    </script> 


Solution

  • You don't need to keep track of markerIndex because You have just only one marker.

    Moreover, I believe You don't even need to force the placement of the marker inside the already selected region, as You can simply select a new region and place the marker inside it at the same time - up to You. Anyway, if You absolutely need this feature, You can simply store that previously selected region and check the new selection against that old code.

    I my demo the marker can be placed only inside a region, not on the sea.

    But: the original maps from jVectorMap doesn't includes some tiny countries like Mauritius, Seychelles and so on. They are simply too small, You would need to zoom-in a lot. The preferred solution for this problem is to place additional markers at their location.

    Another solution could be to switch to a full-countries world map. Here is an example: jvectormap-all-countries.

    $(document).ready(function() {
    
      var selectedRegion = "";
      
      var map = new jvm.Map({
        map: "world_mill_en",
        container: $('#map'),
        zoomOnScroll: true,
        regionsSelectable: true,
        regionsSelectableOne: true, 
        backgroundColor: "aliceblue",
        regionStyle: {fill:'black', selected: {fill: 'red'}},
        markerStyle: {initial: {fill: 'yellow'}},
        hoverColor: '#FCEF06',
        hover: {stroke: 'black', "stroke-width": 2, fill:'#FCEF06'},
        markers: [],
        series: {markers: [{attribute: 'fill', scale: {}, values: []}]},
        onMarkerClick: function(e, code) {
           map.tip.hide();
        },
        onMarkerTipShow: function(e, label, code) {
          var coords = map.markers[code].config.latLng;
          map.tip.text(coords[0].toFixed(2) + ', ' + coords[1].toFixed(2));
        }
      });
    
      map.container.on("click", function(e){
        var name = "MARKER",
            latLng = map.pointToLatLng(
              e.pageX - map.container.offset().left,
              e.pageY - map.container.offset().top
            ),
            targetCls = $(e.target).attr('class');
        if(latLng) {
          var currentRegion = map.getSelectedRegions()[0];
          var isRegion = targetCls && ~targetCls.indexOf("jvectormap-region");
          var isMarker = targetCls && ~targetCls.indexOf("jvectormap-marker");
          if (isRegion) {
            var isSameRegion = selectedRegion === currentRegion;
            selectedRegion = currentRegion;
            map.removeAllMarkers();
            map.addMarker(name, {latLng: [latLng.lat, latLng.lng]});
          }
        }
      });
    
    });
    <!DOCTYPE html>
    <html>
    
    <head>
      <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/jquery-jvectormap.min.css" type="text/css">
      <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/jquery-jvectormap.min.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/tests/assets/jquery-jvectormap-world-mill-en.js"></script>
    </head>
    
    <body>
      <div id="map" style="width: 800px; height: 600px"></div>
    </body>
    
    </html>