1

I'm new to Javascript and have had some help, but still trying to wrap my head around the solution. I'm trying to apply the .mapplic-active class to all states listed on the map when active. An example can be seen here: http://test.guidehunts.com/concealed-weapons-permit-reciprocity-map/?location=nv. I'm trying to get a string from location.description, split the states, then apply the class through the results of an array, but running into issues. This is what I'm trying to edit.

function Tooltip() {
        this.el = null;
        this.shift = 6;
        this.drop = 0;
        this.location = null;

        this.init = function() {
            var s = this;

            // Construct
            this.el = $('<div></div>').addClass('mapplic-tooltip');
            this.close = $('<a></a>').addClass('mapplic-tooltip-close').attr('href', '#').appendTo(this.el);
            this.close.on('click touchend', function(e) {
                e.preventDefault();
                $('.mapplic-active', self.el).attr('class', 'mapplic-clickable');
                if (self.deeplinking) self.deeplinking.clear();
                if (!self.o.zoom) zoomTo(0.5, 0.5, 1, 600, 'easeInOutCubic');
                s.hide();
            });
            this.image = $('<img>').addClass('mapplic-tooltip-image').hide().appendTo(this.el);
            this.title = $('<h4></h4>').addClass('mapplic-tooltip-title').appendTo(this.el);
            this.content = $('<div></div>').addClass('mapplic-tooltip-content').appendTo(this.el);
            this.desc = $('<div></div>').addClass('mapplic-tooltip-description').appendTo(this.content);
            this.link = $('<a>' + mapplic_localization.more_button + '</a>').addClass('mapplic-tooltip-link').attr('href', '#').hide().appendTo(this.el);
            this.triangle = $('<div></div>').addClass('mapplic-tooltip-triangle').prependTo(this.el);

            // Append
            self.map.append(this.el);
        }

        this.set = function(location) {
            if (location) {
                var s = this;

                if (location.image) this.image.attr('src', location.image).show();
                else this.image.hide();

                if (location.link) this.link.attr('href', location.link).show();
                else this.link.hide();

                this.title.text(location.title);
                this.desc.html(location.description);
                this.content[0].scrollTop = 0;

                this.position(location);
            }
        }

        this.show = function(location) {
            if (location) {
                if (location.action == 'none') {
                    this.el.stop().fadeOut(300);
                    return;
                }

                var s = this;

                this.location = location;
                if (self.hovertip) self.hovertip.hide();

                if (location.image) this.image.attr('src', location.image).show();
                else this.image.hide();

                if (location.link) this.link.attr('href', location.link).show();
                else this.link.hide();

                this.title.text(location.title);
                this.desc.html(location.description);

                // Shift
                var pinselect = $('.mapplic-pin[data-location="' + location.id + '"]');
                if (pinselect.length == 0) {
                    this.shift = 20;
                }
                else this.shift = pinselect.height() + 10;

                // Loading & positioning
                $('img', this.el).load(function() {
                    s.position();
                });
                this.position();

                // Making it visible
                this.el.stop().show();
            }
        }
kevinje
  • 13
  • 6

1 Answers1

0

I would recommend using jQuery plugin and trying this

<script src="http://code.jquery.com/jquery-1.12.1.min.js"></script>
<script>
    var locations=location.description;

    //strip tags
    locations = locations.replace(/(<([^>]+)>)/ig,"");

    //take states after :
    locations = locations.split(':');

    //set locations to states (after the text)
    locations=locations[1];

    //make states lowercase to match id's
    locations = locations.toLowerCase();

    //remove carriage returns
    locations = locations.replace('\n',"");

    //locations var jquery array
    locations = locations.split(',');

    //loop array and add class
    $.each( locations, function( key, state ) {
        $("#"+state).attr("class", "mapplic-active");
        //$("#"+state).addClass('mapplic-active');
    });
</script>
  1. Since the description has other text and tags, lets strip the html tags out and split it using :. We would then take the second portion being the states only.
  2. The second split command will split the states into an array.
  3. The each command will loop through the locations
  4. The addClass will then apply the class to just the states that were past back from the description.
  5. Don't forget to reset the actives by doing something like this

$(".mapplic-active").removeClass('mapplic-active');

sgtcoder
  • 144
  • 6
  • Thanks mjbrancato, I added this with still no luck. I inserted the jquery snippet in this.set = function(location) with no luck. Could the uppercase state abbreviations in the description be causing this? – kevinje Mar 08 '16 at 08:57
  • The states and ID's should be case sensitive so make sure you are using the correct ones. I tested this code myself and it worked for me. So if it doesn't for you, you might need a modification. What doesn't work? Does it give an error message in console log? – sgtcoder Mar 08 '16 at 14:15
  • Yes, this is what I'm currently getting in the console: . util.js:218 Google Maps API warning: NoApiKeys https://developers.google.com/maps/documentation/javascript/error-messages#no-api-keys jquery.js?ver=1.11.3:2 Uncaught Error: JQMIGRATE: Invalid selector string (XSS) – kevinje Mar 09 '16 at 06:45
  • I left it up so you can see it here: http://test.guidehunts.com/concealed-weapons-permit-reciprocity-map/ – kevinje Mar 09 '16 at 06:46
  • Were you getting this API key error before putting the code in I provided? Or did it just started happening recently? Which JavaScript file are you working out of? I also noticed this is a Wordpress site as well. – sgtcoder Mar 09 '16 at 15:33
  • And is there a valid API key from Google set in there? – sgtcoder Mar 09 '16 at 15:58
  • The site is built off of Wordpress and both errors are brand new. I'm working from the main mapplic.js file. How do I figure out if there is a valid API key? – kevinje Mar 09 '16 at 23:07
  • The main way is when you use it through the API it gives back an error. Is this a valid API key from Google? And did you add the domain in the Google Dev account? – sgtcoder Mar 09 '16 at 23:15
  • Can you do a console.log(put varible here) on the `var description=location.description; ` string? Just to verify it's correct? I wrote the code snippet assuming the string was in this format: "AZ,KY". That split command then splits that in an array where you loop it. Try this tutorial for testing API key. I am pretty sure you should be using the JavaScript API. Just throw up a temp page with your API key in there: https://developers.google.com/maps/documentation/javascript/tutorial#Audience – sgtcoder Mar 09 '16 at 23:20
  • I see the description response in the JSON being:

    Below is a list of states that honor your permit:\nWA,ID,AZ,MT,WY,TX,OK ,KS,NE,SD,ND,LA,AR,MO,IA,WI,MS,AL,GA,TN,KY,IN,OH,WV,VA,NC,VT,DE,AK

    So the code I gave you would only loop through if it was just those state codes. We will have to add more stuff to that to extract those.
    – sgtcoder Mar 09 '16 at 23:25
  • Please see my updated answer. I updated the code to support the added text and the added description text in there. I have an example running here. It simply takes the description that gets pasted back, changes it to an array, and the loop will display each state separately. The code snippet I updated for you will loop and do the classes instead: http://dev-mjbcode.com/maptest/ – sgtcoder Mar 09 '16 at 23:40
  • Thanks for breaking it down like that. It really helped. However I'm still getting an error similar to this for all states: Uncaught Error: Syntax error, unrecognized expression: # WA. The API issue was due to a plugin. I deactivated it and all was fine but lost some functionality. Do you know what would cause this? Is it the wrong api key within one of the documents? I don't think it has any calendar functionality so I thought it was a bit weird. – kevinje Mar 10 '16 at 08:04
  • Also, I noticed your ID's are lowercase. You might have to do this: after `locations=locations[1];` put this `locations = locations.toLowerCase();` – sgtcoder Mar 10 '16 at 08:26
  • Also discovered that there were carriage returns. I added this too: `locations = locations.replace('\n',"");` please see updated answer for clarification. We are getting close. – sgtcoder Mar 10 '16 at 08:33
  • I was so excited to get to this after work. It looks like it's having problems identifying locations. I'm getting this error for some reason. Uncaught TypeError: Cannot read property 'toLowerCase' of undefined – kevinje Mar 11 '16 at 04:47
  • Update: I am only getting the error for states that do not contain that string which makes sense, so no problem there (states that issue to residents only on second map). This is great news, but no classes are currently being applied to the id's. – kevinje Mar 11 '16 at 04:59
  • The TypeError error is because of the funky response you get back for some of them. It's probably in a different format. Please may you provide an example of this? Or you should be able to update the description for that. For the ID's not working, keep in mind that you can only have 1 id for 1 page. So having two maps with the same ID's will cause it not to work. Classes you can have duplicate on a page. Try removing a map to test it out. – sgtcoder Mar 11 '16 at 07:24
  • I'm not worried about the TypeError as some of the states do not contain any other states to apply the id to. I did remove one of the maps and the id's are still not being applied. After looking everything up, I can't seem to find a reason why this wouldn't be firing. – kevinje Mar 12 '16 at 04:34
  • That is very strange. Can you add `console.log("Locations: " + locations);` after this `locations = locations.split(',');` for troubleshooting? It should list out an array of the locations in the console. I wonder if it's even reaching those ID's for some reason. – sgtcoder Mar 12 '16 at 05:21
  • I definitely see the list of locations in an array when setting a breakpoint so that part is working. The only part that is not working is the call to the addClass. I know it works on a test page, so it's got to be something with the map blocking it or something. Or it might be resetting the classes after we set them. – sgtcoder Mar 12 '16 at 05:52
  • Please see updated response... based on this SO answer for SVG classes: http://stackoverflow.com/questions/8638621/jquery-svg-why-cant-i-addclass – sgtcoder Mar 12 '16 at 05:58
  • `$("#"+state).attr("class", "mapplic-active");` update in case you didn't see it – sgtcoder Mar 12 '16 at 06:05
  • Thanks for the update. I got it working, but haven't been able to figure out how to remove the class successfully. Here is what I have thus far: $.each( locations, function( key, state ) { var selectedstates1 = $("#"+state).children(); var selectedstates2 = $("#"+state); var allstates = $('svg').find('g,path') selectedstates1.add(selectedstates2).attr("class", "mapplic-opacity"); allstates.not(selectedstates1.add(selectedstates2)).removeClass("mapplic-opacity"); }); – kevinje Mar 13 '16 at 07:04
  • Is that all the extra code you had to put in there jjst to get it working? The code I provided should work as well as it was said to be working from StackOverflow. Have you tried this before the each statement: `$(".mapplic-active').attr("class", "mapplic-clickable");` – sgtcoder Mar 13 '16 at 07:59
  • Yeah, I was having an issue with .mapplic-clickable being applied after the code we were firing. .mapplic-active fires, but then quickly goes back to .mapplic-clickable, even with the above snippet. – kevinje Mar 13 '16 at 18:27
  • Yah, that's very strange. The map has to be running extra stuff after our events fire. – sgtcoder Mar 13 '16 at 18:30
  • Happy to say I found the issue. Here is the code snippet with commented out issue: //$('.mapplic-active', self.el).attr('class', 'mapplic-clickable'); if (location.onmap) location.onmap.attr('class', 'mapplic-active'); if ((self.o.deeplinking) && (!check)) self.deeplinking.update(id); Do I need this or am I Okay without it? – kevinje Mar 13 '16 at 19:06
  • Was that the built-in code that was in the JS file? Well it looks like it is working now so I would say it's safe to leave commented out for now. That's crazy you had to modify the existing mapplic code. Well I am glad you got this working and that my code helped out. That's awesome! – sgtcoder Mar 13 '16 at 19:40
  • Thanks again for the support. I couldn't have done it without you. – kevinje Mar 13 '16 at 19:51