1

I have a script that requires jQuery, and I don't know how to add it into a post correctly. I've read How to include jQuery and JavaScript files correctly? and Using JavaScript and JQuery in Page but they are too advanced for me to understand. The Scripts 'n Styles plugin has the Include Scripts section, which I suspect is another way to use wp_enqueue_script, but I don't know which one to choose:

So far, I only add the <head> and <body> elements without the jQuery, and while it ultimately worked, it didn't work at the beginning and I had to tried many times. So is there a proper and easy way to do this?


FYI: How to add JavaScript code on WordPress correctly?


The code is below.

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script>
    var words = [];

    words.push('vocabulary');
    words.push('lexicon');
    words.push('lexicons');

  </script>

</head>

<body>

  <p id="demo">A vocabulary is a list of words that an individual knows or uses regularly. vocabulary is different from lexicon because vocabulary is about what an individual or group of people know, whereas lexicon is about the language itself. In this paragraph, lexicons is a new word that's added, so don't forget to push 'lexicons' in your array.
  </p>

  <script>
    function toggle(element) {
      if (element.innerHTML.split('_').join('').trim().length === 0) {
        element.innerHTML = element.getAttribute("word");
      } else {
        element.innerHTML = "_______";
      }
    }

    $.each(words, function(index, value) {
      var replacestr = new RegExp('\\b'+value+'\\b', "g");
      $("p#demo:contains('" + value + "')").html(function(_, html) {
        return html.replace(replacestr, ' <span class = "smallcaps" word="' + value + '" onclick="toggle(this)">_______</span>')
      });
    });
  </script>
</body>

</html>
7
  • Your sample code does not include any WordPress function calls. Are you trying to develop a theme?
    – cjbj
    Commented Aug 23, 2018 at 16:06
  • No, I just want to know how to add jQuery properly in WP, and I think it's on-topic. See How to add JavaScript code on WordPress correctly?
    – Ooker
    Commented Aug 23, 2018 at 16:13
  • 1
    jQuery is loaded automatically by WP if you have a decent theme that has the line wp_head() somewhere between <head> and </head>
    – cjbj
    Commented Aug 23, 2018 at 16:15
  • can you elaborate that, or give a resource so I can learn more?
    – Ooker
    Commented Aug 23, 2018 at 16:17
  • Sorry, I have no idea what you are trying to do. The code you give is the rudimental start of a theme. But it also looks like you are trying to customize an existing plugin. The best thing would probably to learn a bit more about how WordPress works, so you can ask your question in a way that is understandable to others. You may start here: codex.wordpress.org/Theme_Development#Anatomy_of_a_Theme and here: codex.wordpress.org/Writing_a_Plugin#Programming_Your_Plugin
    – cjbj
    Commented Aug 23, 2018 at 16:26

2 Answers 2

3

assuming you have enqueued everything ( script files and style files ) properly in your wordpress theme's folder

following would be ( just assume ) your theme files

wp-content/themes/your-theme-dir/
                   assets/
                      css/   ( this is directory/folder )
                        styles.css  ( this is file )
                      js/
                        scripts.js
                   index.php
                   functions.php

lets say your code shown above is in index.php

now assuming you've included your scripts.js file from functions.php file

the content in your scripts.js file should look like:

(function($){
    var words = [];

    words.push('vocabulary');
    words.push('lexicon');
    words.push('lexicons');
    function toggle(element) {
      if (element.innerHTML.split('_').join('').trim().length === 0) {
        element.innerHTML = element.getAttribute("word");
      } else {
        element.innerHTML = "_______";
      }
    }

    $.each(words, function(index, value) {
      var replacestr = new RegExp('\\b'+value+'\\b', "g");
      $("p#demo:contains('" + value + "')").html(function(_, html) {
        return html.replace(replacestr, ' <span class = "smallcaps" word="' + value + '" onclick="toggle(this)">_______</span>')
      });
    });
})(jQuery);

Remember when enqueunig scripts your file should be dependent upon jquery like

wp_enqueue_script( 'file-id', 'path-to-file', array( 'jquery' ), 'version-number', 'true' );

for getting path to file, you have two options

  1. if your theme is parent theme use: get_template_directory_uri() e.g. get_template_directory_uri().'/assets/js/scripts.js'

  2. if your theme is child theme use: get_stylesheet_directory_uri() e.g. get_stylesheet_directory_uri().'/assets/js/scripts.js'

4
  • I tested this in its strict html format, and the code works. Then I created a plugin, enqueued jQuery and the script, created a template and linked it to a page. The ".each" part of the script runs but the Console reports an error "Uncaught ReferenceError: toggle is not defined at HTMLSpanElement.onclick". It's probably a very simple issue, but there's seems to be something in WordPress that affects the running of the code.
    – Tedinoz
    Commented Aug 24, 2018 at 12:19
  • Please add the code you wrote.
    – maverick
    Commented Aug 24, 2018 at 13:48
  • That's the only way I/anyone can help
    – maverick
    Commented Aug 24, 2018 at 13:48
  • You are quite right. Apologies. I was rushing to flag the issue and being in a different time zone, I couldn't followup immediately. Please Refer my alternative answer.
    – Tedinoz
    Commented Aug 25, 2018 at 2:37
2

I tested this code in its strict html format, and the jQuery works.

Then I coded answers to this question in WordPress as 1) a plugin and 2) loaded from functions.php. In each case, the jQuery fails.

The problem appears, to my untrained eye, to be related to the Javascript. Specifically because the method "toggle(element)" is a global object at the time that "$.each" is executed. Somewhere along the line, I believe that the two need to be inter-linked but despite spending the better part of a day on this, it is beyond my ability. Of course, there's the risk of PEBCAK.

The content as displayed (proving that $.each has run successfully)
enter image description here

The content HTML enter image description here

Chrome Console before clicking on the text:
enter image description here

Chrome Console after clicking on a blank work in the text

enter image description here


The Plugin consists of:
1 - The Plugin file (vocab.php)
2 - The Plugin Javascript file (vocab.js)
3 - The Plugin Template content file (vocab-template.php)
4 - The Page Template (page-vocab.php) (Template name = Vocab Test)
Plus One Standard WordPress Page, template = "Vocab Test"

The Plugin file (vocab.php)

<?php
/*
Plugin Name: a_Stackoverflow_Vocab test
*/
// 01 - Define the filesystem paths for the plugin

if ( ! defined( 'WP_CONTENT_URL' ) )
      define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
if ( ! defined( 'WP_CONTENT_DIR' ) )
      define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( ! defined( 'WP_PLUGIN_URL' ) )
      define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
      define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
define( 'VOCAB_DIR', plugin_dir_path( __FILE__  ) );
define( 'VOCAB_URL', plugin_dir_url( __FILE__  ) );

// 02 - Enqueue scripts and styles for the plugin. 

function vocab_scripts() {
    if (!is_admin()) {
            if (is_page(array('vocab'))) { 
                wp_enqueue_script( 'jquery' );
                wp_register_script('vocabjs',  VOCAB_URL . 'vocab.js', array( 'jquery'),NULL);  
                wp_enqueue_script('vocabjs'); 
            }
    }
}
add_action( 'wp_enqueue_scripts', 'vocab_scripts' );

// Calls to key files: template layout

require("vocab-template.php"); 

?>

The Javascript file (vocab.js)

jQuery(document).ready(function ($) {
    var words = [];
    words.push('vocabulary');
    words.push('lexicon');
    words.push('lexicons');

function toggle(element) {
  if (element.innerHTML.split('_').join('').trim().length === 0) {
    element.innerHTML = element.getAttribute("word");
  } else {
    element.innerHTML = "_______";
  }
}

$.each(words, function(index, value) {
  var replacestr = new RegExp('\\b'+value+'\\b', "g");
  $("p#demo:contains('" + value + "')").html(function(_, html) {
    return html.replace(replacestr, ' <span class = "smallcaps" word="' + value + '" onclick="toggle(this)">_______</span>')
  });
});
});

The Plugin Template content file (vocab-template.php)

<?php
/*
*       function to deliver template
*/
function insert_vocab_template(){
?>
<div id="page">
<!-- start div page -->
    <h1>Vocabulary Test</h1>
        <div id="cover_content">
            <h2>Test content</h2>
                <p id="demo">A vocabulary is a list of words that an individual knows or uses regularly. vocabulary is different from lexicon because vocabulary is about what an individual or group of people know, whereas lexicon is about the language itself. In this paragraph, lexicons is a new word that's added, so don't forget to push 'lexicons' in your array.</p>
        </div>
        <!-- end cover_content -->
    </div> 
    <!-- end #page -->
<?php
}
?>

The Page Template (page-vocab.php)

<?php /* Template Name: Vocab Test */ ?>
<?php
get_header(); ?>
    <div id="primary" class="content-area">
        <main id="main" class="site-main" role="main">
        <!-- page -->
            <?php
            $myoutput = insert_vocab_template();
            echo $myoutput;
            ?>
        </main><!-- .site-main -->
    </div><!-- .primary -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

Alternative via Functions.php (in a child theme)

1 - Enqueue function in Functions.php
2 - The Javascript file (themes/childtheme/js) - vocab2.js (identical to plugin version)
3 - The Page Template (page-vocab2.php) (Template name = Vocab2 Test)
Plus One Standard WordPress Page, template = "Vocab Test2"
Note: in this version, the paragraph of text (with id="demo") was included in the WordPress page as content.

Extract from Functions.php

// enqueue jquery and script
function vocab2_scripts() {
    if (!is_admin()) {
            if (is_page(array('vocab2'))) { 
                wp_enqueue_script('jquery');
                wp_enqueue_script('vocab2js', get_stylesheet_directory_uri(). '/js/vocab2.js', array( 'jquery' ));  
            }
    }
}
add_action( 'wp_enqueue_scripts', 'vocab2_scripts' );

The Javascript file (themes/childtheme/js) - vocab2.js

jQuery(document).ready(function ($) {
    var words = [];

    words.push('vocabulary');
    words.push('lexicon');
    words.push('lexicons');

    function toggle(element) {
      if (element.innerHTML.split('_').join('').trim().length === 0) {
        element.innerHTML = element.getAttribute("word");
      } else {
        element.innerHTML = "_______";
      }
    }

    $.each(words, function(index, value) {
      var replacestr = new RegExp('\\b'+value+'\\b', "g");
      $("p#demo:contains('" + value + "')").html(function(_, html) {
        return html.replace(replacestr, ' <span class = "smallcaps" word="' + value + '" onclick="toggle(this)">_______</span>')
      });
    });
});

The Page Template (page-vocab2.php) (Template name = Vocab2 Test)

<?php /* Template Name: Vocab Test2 */ ?>
<?php
get_header(); ?>
<div id="primary" class="content-area">
    <main id="main" class="site-main" role="main">
    <!-- page -->
        <?php
        while ( have_posts() ) : the_post();
        ?>
            <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
                <header class="entry-header">
                    <?php the_title( '<h1 class="entry-title">', '</h1>' ); ?>
                </header><!-- .entry-header -->

                <div class="entry-content">
                    <?php the_content();?>
                </div><!-- .entry-content -->
            </article><!-- #post-## -->
        <?php
            // End of the loop.
        endwhile;
        ?>
    </main><!-- .site-main -->
</div><!-- .content-area -->
<?php get_sidebar(); ?>
<?php get_footer(); ?>

UPDATE:

I can now get the code to work by calling "toggle" from with the "$.each" statement but the Console is still giving errors - now changed to:
"Uncaught TypeError: Cannot read property 'innerHTML' of undefined" enter image description here

The Javascript file now looks like this:

function toggle(element) {
      if (element.innerHTML.split('_').join('').trim().length === 0) {
        element.innerHTML = element.getAttribute("word");
      } else {
        element.innerHTML = "_______";
      }
}

jQuery(document).ready(function ($) {
    var words = [];

    words.push('vocabulary');
    words.push('lexicon');
    words.push('lexicons');
    $.each(words, function(index, value) {
      var replacestr = new RegExp('\\b'+value+'\\b', "g");
      $("p#demo:contains('" + value + "')").html(function(_, html) {
        return html.replace(replacestr, ' <span class = "smallcaps" word="' + value + '" onclick="toggle(this)">_______</span>')
      });
    });
        toggle();
});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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