0

I need to attach an event to the category buttons in the Hero Maps plugin for Wordpress. The code I am using currently is not working as expected:

Code generated by Wordpress plugin:

<div id="" class="hmapsprem_cat_tab_container ">
 <div id="hmapsprem_tab_cat_sel_0" class="hmapsprem_cat_tab active" ><a>CULTURE</a></div>
 <div id="hmapsprem_tab_cat_sel_1" class="hmapsprem_cat_tab active"><a>DINING</a></div>
 <div id="hmapsprem_tab_cat_sel_2" class="hmapsprem_cat_tab active"><a>HOTEL</a></div>
 <div id="hmapsprem_tab_cat_sel_3" class="hmapsprem_cat_tab active"><a>RETAIL</a></div>
 <div id="hmapsprem_tab_cat_sel_5" class="hmapsprem_cat_tab active"><a>z199W</a></div>
 <div style="clear:both;"></div>
</div>

My jQuery:

$(".hmapsprem_cat_tab_container > div").click(function(){
    var id = $(this).attr('id');
    console.log(id);
});

Nothing is being logged to the console. Is the plugin somehow denying me access to these elements?

Philip Smith
  • 327
  • 4
  • 17

3 Answers3

2

Wordpress runs jQuery in noConflict mode. This is done in order to allow plugins dependent on a specific jQuery version to load their own version of jQuery and not conflict with the one Wordpress uses.

For you, this means that you need to wrap any jQuery code you might have into a function, passing it the jQuery object:

(function($) {
  // $ works here...
})(jQuery)

An alternative would be to use jQuery instead of $ in all your jQuery code.

Also, make sure you run your code when what you expect to be there is there. As in...

(function($) {
  // on dom loaded:
  $(document).ready(){
     // stuff
  }

  // on page loaded:
  $(window).on('load', function(){
    // stuff
  })
})(jQuery)

After you wrap your jQuery code into the noConflict wrapper, if it still does not work, do a console.log(this) before your var declaration, to make sure that code is executed and to find out what this object is in that context.

Maybe your .hmapsprem_cat_tab_container > div selector is faulty and that's the problem with your code.

Note: a way superior way to bind, especially in WordPress, where any plugin can make an ajax call and change DOM dynamically, is to bind on containers you can count on.

For example, let's assume your page container has id of main-container. Instead of adding one binding for each element in the .hmapsprem_cat_tab_container > div collection, you make only one binding on the container you can count on:

$('#main-container').on('click', '.hmapsprem_cat_tab_container > div', function(e) {
  console.log(e, this);
})

Not only you replace multiple event bindings with one, but you also get the huge advantage the selector gets evaluated when the event happens, not when the binding is done. Which means the binding will work (if the click was made inside an .hmapsprem_cat_tab_container > div element) even on dynamically added elements, not present in DOM when the binding was made.
Obviously, you can replace #main-container with any other valid parent of your .hmapsprem_cat_tab_container > div elements, including document.
The rule of thumb is to find (and bind on) the most specific parent which contains all children you wish to target. The function will not run if the event is triggered on children placed outside of the container you bound on!


Last, but not least: you should be adding you JavaScript to WordPress using wp_enqueue_script and, for this case, you should specify jQuery as dep of your script:

function enqueue_my_jquery_script() {
  wp_enqueue_script(
    'some_specific_script_name',
    get_template_directory_uri('path/to/file.js',__FILE__),
    ['jquery']
  );
}

add_action( 'wp_enqueue_scripts', 'enqueue_my_jquery_script' );  

The above snippet should go inside functions.php of your active theme and you should make sure it's not placed inside another php function if you have any defined in that file. path/to/ should be relative to active theme folder, file.js should contain your jQuery script, wrapped in wrapper shown above.

tao
  • 82,996
  • 16
  • 114
  • 150
1

Did you include the jquery.min.js library? https://www.w3schools.com/jquery/jquery_get_started.asp

$(".hmapsprem_cat_tab_container > div").click(function(){
    var id = $(this).attr('id');
    console.log(id);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="" class="hmapsprem_cat_tab_container ">
 <div id="hmapsprem_tab_cat_sel_0" class="hmapsprem_cat_tab active" ><a>CULTURE</a></div>
 <div id="hmapsprem_tab_cat_sel_1" class="hmapsprem_cat_tab active"><a>DINING</a></div>
 <div id="hmapsprem_tab_cat_sel_2" class="hmapsprem_cat_tab active"><a>HOTEL</a></div>
 <div id="hmapsprem_tab_cat_sel_3" class="hmapsprem_cat_tab active"><a>RETAIL</a></div>
 <div id="hmapsprem_tab_cat_sel_5" class="hmapsprem_cat_tab active"><a>z199W</a></div>
 <div style="clear:both;"></div>
</div>

Check if JQuery is available: Checking if jquery is loaded using Javascript

Also, check that the selector is correct.

In this case, it is; however, if the html elements are in other parts of the code or loaded via iFrame then your selector needs to be changed.

One way to do this is by doing right-click on the html element and do Inspect. Then, see what is the selector that the browser detects.

acarlstein
  • 1,799
  • 2
  • 13
  • 21
  • The site is running on Wordpress which uses jQuery 1.12.4 as well as jQuery migrate 1.4.1 – Philip Smith Aug 06 '18 at 18:56
  • First, check if jQuery is loaded: https://stackoverflow.com/questions/7341865/checking-if-jquery-is-loaded-using-javascript. – acarlstein Aug 06 '18 at 18:58
  • Then, check if the selector is correct. Do this by doing right click on the element and check what is the selector that the browser detect when doing Inspect. – acarlstein Aug 06 '18 at 18:58
0

Check if jQuery is properly loaded into your project by going to DevTools, than go to Sources tab and on the left side try to find jQuery file that you've attached to the project.

If the file is attached by CDN, simply press CTRL + U/ CMD + U and check if it's properly included.

I can see that you're trying to attach this click event o multiple elements.

Try to use event bubbling mechanism, so fire your click event on the document - it's more efficient.

$(document).on('click', '.hmapsprem_cat_tab', function(event) {
    const singleTab = $('.hmapsprem_cat_tab');
    console.log(singleTab);
});

Inside of this code try to console.log these elements to find out if they exist in DOM.

If this still doesn't work try to run this code inside $(document).ready(); function to be sure that everything is loaded before you execute your JavaScript code.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
p7adams
  • 622
  • 1
  • 9
  • 24