0

I have a function that I use for an interactive map, where I hover an element to show a specific region based on class that matches a country suffix. Im trying to figure out how to select multiple classes to show multiple regions.

Code:

var mapObj = jQuery('#vmap').data('mapObject');

            jQuery('#countries').on('mouseover mouseout', 'a:first-child', function (event) {
                // event.preventDefault();
                var elem = event.target,
                    evtype = event.type;

                if (evtype === 'mouseover') {
                    mapObj.select(jQuery(elem).attr('class'));
                } else {
                    mapObj.deselect(jQuery(elem).attr('class'));
                };
            });

};

<ul id="countries">
  <li><a class="SE" href="">Sweden</a></li>
  <li><a class="DK" href="">Denmark</a></li>
</ul>

I might going this the wrong way, but I would like to target mutiple regions by using several classes:

<li><a class="SE DK" href="">Sweden and Denmark</a></li>

This of course doesn't work but illustrates what I want to do. whats the best approach here?

Example:

       jQuery('#vmap').vectorMap({
            map: 'world_en',
onLabelShow: function (event, label, code) {
        
                if (code == 'se') {
                var countryName = label[0].innerHTML;
          var html = ['<span class="tooltip-up arrow-down-center">',
           countryName,
': 50% of production',
          '</span>'
          ].join("");
          label[0].innerHTML = html;
                }
        },
            backgroundColor: '#fff',
            enableZoom: false,
            color: '#ffffff',
            hoverOpacity: 0.7,
            selectedColor: '#666666',
            showTooltip: true,
            values: sample_data,
            scaleColors: ['#C8EEFF', '#006491'],
            normalizeFunction: 'polynomial',                           
            pinMode: 'content',
            regionsSelectableOne: false,
                regionsSelectable: false,
                series: {
                regions: [{
                  scale: ['#C8EEFF', '#0071A4'],
                  normalizeFunction: 'polynomial'
               }]
             }
        });
 var mapObj = jQuery('#vmap').data('mapObject');

            jQuery('#countries').on('mouseover mouseout', 'a:first-child', function (event) {
                // event.preventDefault();
                var elem = event.target,
                    evtype = event.type;

                if (evtype === 'mouseover') {
                    mapObj.select(jQuery(elem).attr('class'));
                } else {
                    mapObj.deselect(jQuery(elem).attr('class'));
                };
            });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://www.10bestdesign.com/jqvmap/assets/jqvmaps/jqvmap.css" media="screen" rel="stylesheet" type="text/css">
<script src="https://www.10bestdesign.com/jqvmap/assets/jqvmaps/jquery.vmap.js"></script>
        <script src="https://www.10bestdesign.com/jqvmap/assets/jqvmaps/maps/jquery.vmap.world.js"></script>
        <script src="https://www.10bestdesign.com/jqvmap/assets/jqvmaps/jquery.vmap.sampledata.js"></script>

  
<div id="vmap" style="width: 800px; height: 400px;"></div>

<ul id="countries">
  <li><a class="SE" href="">Sweden</a></li>
  <li><a class="DK" href="">Denmark</a></li>
   <li><a class="SE DK" href="">Sweden and Denmark</a></li>
</ul>
Jerry
  • 1,069
  • 2
  • 13
  • 31
  • 1
    What does `mapObj.select` actually _do_ with the passed value? – CBroe Feb 18 '22 at 10:55
  • It highlights the matching country on the map from the country suffix- im using JQVmap. – Jerry Feb 18 '22 at 10:57
  • 1
    Then you will probably have to split the value `SE DK` at the space character, and then loop over the resulting array, and call `mapObj.select`/ `mapObj.deselect` for each individually. – CBroe Feb 18 '22 at 11:00
  • @CBroe Yes, something like that is what im trying to achieve,m unsure how to though. Added a codepen with working example to my question. – Jerry Feb 18 '22 at 11:04
  • Please add the codepen code **here**, as a StackOverflow snippet. – connexo Feb 18 '22 at 11:12

2 Answers2

2

You can modify your select/deselect function to accept array of classes, or instead loop the classes and invoke select/deselect for each class name:

var mapObj = jQuery('#vmap').data('mapObject');

        
jQuery('#countries').on('mouseover mouseout', 'a:first-child', function (event) {
  var elem = event.target;
  var countryCodes = jQuery(elem).attr('class').split(/\s+/);

  evtype = event.type;

  if (evtype === 'mouseover') {
    jQuery.each(countryCodes, function(index, code) {
       mapObj.select(code);
    });
  } else {
    jQuery.each(countryCodes, function(index, code) {
      if (mapObj.isSelected(code)) {
        mapObj.deselect(code);
      } else {
        mapObj.select(code);
        mapObj.deselect(code);
      }
    });
  };
});
Plamen Nikolov
  • 2,643
  • 1
  • 13
  • 24
  • The answers seems correct but it wont work with the JQVmap library, I think I looked at this from the wrong angle. – Jerry Feb 18 '22 at 11:30
  • @user3344734 I found a code logic flow, I was not getting the classes as array... so I've updated the code snippet to properly split the multiple classes and loop over each one of them. – Plamen Nikolov Feb 18 '22 at 12:25
  • 1
    Oh - thank you! This does indeed work. For some reason it removes the color of the map on mouseout, but thats another question I guess. – Jerry Feb 18 '22 at 12:45
  • Can it be that the mouseover deselects classes outside the target elements, thus deselecting all countries? – Jerry Feb 18 '22 at 12:54
  • @user3344734 yes, if you have more classes than needed on the `a:first-child` element , it will deselect all of them. – Plamen Nikolov Feb 18 '22 at 13:14
  • Hmm. No, no more classes. But it seems to deselect all classes outside #countries – Jerry Feb 18 '22 at 13:35
  • Also only happens on any element with more then one class, others work fine. – Jerry Feb 18 '22 at 13:50
  • The map colours are selected from a parameter: scaleColors so I think I should start looking at reinitialise it on mouseout – Jerry Feb 18 '22 at 14:25
  • @user3344734 I've refactored my code and have fixed the reported issues with the deselection of multiple regions at once. The issue was caused because the vMap component can have only one selected region in its internal state at a time, the deselect() is only deselecting the last selected region, so that is why when you try to deselect 2 different regions is has a buggy behaviour. I've overcome this bug by simulating a select/deselect on mouse out, so try the code, it is working correctly. – Plamen Nikolov Feb 18 '22 at 14:30
  • Yes, that is it! works exactly as I wanted. Perfect, thanks! – Jerry Feb 18 '22 at 14:34
0

you can split each class and put in foreach loop so all element will target where that class is exist

var mapObj = jQuery('#vmap').data('mapObject');

        jQuery('#countries').on('mouseover mouseout', 'a:first-child', function (event) {
            // event.preventDefault();
            var elem = event.target,
                evtype = event.type;

            var attrClass = jQuery(elem).attr('class');
            var claArr = attrClass.slit(" ");
            jQuery(claArr).each(function(index,values){
                if (evtype === 'mouseover') {
                    mapObj.select(values);
                } else {
                    mapObj.deselect(values);
                };
            });    
            if (evtype === 'mouseover') {
                mapObj.select(jQuery(elem).attr('class'));
            } else {
                mapObj.deselect(jQuery(elem).attr('class'));
            };
        });

};