9

Is there a way to put javascript in the URL portion of a WordPress menu item? I have a live chat function on my site, and I am supposed to put this code onto the site to make a link to open the live chat (as suggested here).

<!-- BEGIN OLARK CHAT LINK -->
<a href="javascript:void(0);" onclick="olark('api.box.expand')">
    Click here to chat!
</a>
<!-- END OLARK CHAT LINK -->

The client wants the link in the utility nav bar, which was created used a WordPress menu in the WordPress dashboard. But when I copy and paste javascript:void(0);" onclick="olark('api.box.expand') into the URL box in the WordPress dashboard, it just disappears and the link remains inactive.

Something I read said that maybe I could put a custom class on the link in question and then write a Javascript function that fires when the link with that class is clicked. I tried that, though, and I couldn't get it to work. I don't know much Javascript, so it's possible I was writing it entirely wrong.

Does anyone know how to do this? I would like to do it without using a plugin.

  • You shouldn't be able to add javascript to the menu via the user interface, and you should never rely on the onclick attribute to execute javascript – Tom J Nowell Jul 8 '14 at 20:44
  • Why not? That's the code that the live chat company provided to me. – mcography Jul 8 '14 at 21:15
  • 1
    That doesn't mean it's the right way to do it, look up jQuerys .click() event – Tom J Nowell Jul 8 '14 at 22:08
  • I wasn't trying to say that it was. I was just trying to ask why I should never rely on the onclick attribute. I'll look up .click(). – mcography Jul 9 '14 at 14:21
  • Because HTML is for defining a document, adding an onclick attribute is bad in the same way that adding an inline style tag or attribute is bad, it mixes them up. See this question for why it's bad – Tom J Nowell Jul 9 '14 at 14:29
7

Good that it works. If it's for a client or if you just want a cleaner code, you can do it as @Tom J Nowell suggested.

Add a custom menu item, link it to nowhere or anywhere. Find out the menu item ID (every item has one), and then target that ID with jQuery.

$("#menu-item-num").on("click", function(e){ 
      e.preventDefault();
      // olark code here
});

This way, every time a user clicks on that menu-item the script above will be triggered. You can enqueue the jquery script via functions.php.

Update:

  1. Make sure your olark.js is loading. If you're adding it to the footer or header, inspect your page and make sure the script is there. Also, make sure you're not getting any errors in the browser's console.

  2. Wrap your js with a document ready, so that the script executes at the right time:

    jQuery(document).ready(function($) {
      $("#menu-item-38872").on("click", function(e){
      e.preventDefault();
      olark('api.box.expand');
      });
    });
    

The fact that the link is not loading means there's something wrong with the script itself or the script is not loading at all.

  • Thanks for your answer. I don't know much about Javascript, so can you tell me why your solution is better/cleaner? Just trying to understand. – mcography Jul 9 '14 at 14:27
  • I created a file called olark.js and enqueued it, but the link still just leads to # (because that's where I set it in the Wordpress dashboard). This is what I put in olark.js: $("#menu-item-38872").on("click", function(e){ e.preventDefault(); // olark code here olark('api.box.expand'); }); What am I doing wrong? – mcography Jul 9 '14 at 15:36
  • Ah ha! The jQuery(document).ready(function($) { did the trick! Thanks, @gdaniel! – mcography Jul 9 '14 at 15:42
  • Glad it worked. The idea is to keep script separate from content. That's why it's suggested doing it that way. – gdaniel Jul 9 '14 at 15:52
3

Solution #1 (not ideal, but it works):

// Live Chat Utility Link
add_filter( 'wp_nav_menu_items', 'live_chat_utility_link', 10, 2 );
function live_chat_utility_link ( $items, $args ) {
    if ( $args->theme_location == 'utility' ) {
        $items .= '<li><a href="javascript:void(0);" onclick="olark(\'api.box.expand\')" class="livechat">Live Chat</a></li>';
    }
    return $items;
}

Solution #2 (ideal):

With the help of the comments above, here is the solution that worked for me. I created a new file called olark.js and put this code in it:

jQuery(document).ready(function($) {
    $("#menu-item-38872").on("click", function(e){ 
          e.preventDefault();
          // olark code here
          olark('api.box.expand');
    });
});

Then, I enqueued the script in my functions.php with the following code:

function olark_script() {
    wp_register_script( 'olark', get_stylesheet_directory_uri() . '/js/olark.js', array(), '1.0.0', true );
    wp_enqueue_script( 'olark' );
}

add_action( 'wp_enqueue_scripts', 'olark_script' );

If it doesn't work, make sure you are enqueuing your script properly. I am using a child theme, so I had to use get_stylesheet_directory_uri() instead of get_template_directory_uri().

1

I think there is a 'more reliable' option. Relying on the menu item number is not garanteed to work if you migrate your code from development to production for example. If you turn the number into a setting it is getting better, but still not really good.

An alternative could be to link to a non-existent anchor, like #olark, from your menu-item. This can be set using the user-interface and is reliable accross environments. Then your separate script should observe the hash-change (in the browser address bar) and act accordingly.

A simple coffee script example that compiles into javascript that listens to the hashchange:

if window.addEventListener
  window.addEventListener 'hashchange', (event) =>
  @showLogin()
else
  window.attachEvent 'onhashchange', (event) =>
  @showLogin()
#enable sharing the url
if location.hash then @showLogin()

@showLogin is a function that displays a dialog that let's you login if the hash is equal to '#login'.

[edit] Funny enough, the hash in the address does not change if you click a menu item. This is unexpected and could be due to another script preventing the default event. So I had to add another line, to make the window location change in response to clicking a link:

# make sure the hash changes when a link in the menu is clicked (somehow, it doesn't in my case)
$('.menu-item a').click (event) =>
  window.location = $(event.currentTarget).attr 'href'

[/edit]

-2

You can use this to functions.php to add addition script in nav-menu item

function add_nav_class($output) {
$output= preg_replace('/<a/', '<a id="join_club" onclick="awf_Form_.showForm(); return false;"', $output, -1);
return $output;
}
add_filter('wp_nav_menu', 'add_nav_class');
  • This is not a proper solution, it will completely break the menu, because all buttons will be affected, and it doesn't do what the question was about. – Milan Petrovic Nov 15 '17 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.