skip to Main Content

I’m using the following js file in the following manner to achieve the read more functionality in the Product Category description in woocommerce.

function myFunction() {
  var dots = document.getElementById("dots");
  var moreText = document.getElementById("more");
  var btnText = document.getElementById("myBtn");

  if (dots.style.display === "none") {
    dots.style.display = "inline";
    btnText.innerHTML = "Read more"; 
    moreText.style.display = "none";
  } else {
    dots.style.display = "none";
    btnText.innerHTML = "Close Biography"; 
    moreText.style.display = "inline";
  }
}

Along with this css

#more {display: none;}

I’m using the above js file in the functions file as follows

function enqueue_read_more_script() {
  wp_enqueue_script( 'read-more-script', get_stylesheet_directory_uri() . '/js/read-more-script.js', array(), '1.0', true );
}
add_action( 'wp_enqueue_scripts', 'enqueue_read_more_script' );

In the product category description I’m using the following to place the "Read more" break off.

<span id="dots"></span><span id="more">

and at the end of the description using the following to close (Read less)

<span onclick="myFunction()" id="myBtn">Read more</span>

So for example, it would look like this (screenshot also attached)

Lorem Ipsum is simply dummy text of the printing and typesetting industry. <span id="dots"></span><span id="more">
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
<span onclick="myFunction()" id="myBtn">Read more</span>

enter image description here

Once I click update the spans disappear but the "Read More" at the end displays as text both on the front end and at the product category description in the backend.

I’m not sure what I need to do to get the code to work.

2

Answers


  1. Chosen as BEST ANSWER

    Two solutions that worked.

    SOLUTION 1 Most efficient solution as posted by @mina above with some modification/addition.

    JS file in child theme /js/read-more.js

    jQuery(document).ready(function($) {
      function myFunction() {
        var dots = $("#dots");
        var moreText = $("#more");
        var btnText = $("#myBtn");
    
        if (dots.css("display") === "none") {
          dots.css("display", "inline");
          btnText.text("Read more");
          moreText.css("display", "none");
        } else {
          dots.css("display", "none");
          btnText.text("Close Biography");
          moreText.css("display", "inline");
        }
      }
    
      $("#myBtn").on("click", myFunction);
    });
    

    in functions file

        // Allow HTML in term (category, tag) descriptions
    foreach ( array( 'pre_term_description' ) as $filter ) {
        remove_filter( $filter, 'wp_filter_kses' );
        if ( ! current_user_can( 'unfiltered_html' ) ) {
            add_filter( $filter, 'wp_filter_post_kses' );
        }
    }
     
    foreach ( array( 'term_description' ) as $filter ) {
        remove_filter( $filter, 'wp_kses_data' );
    }
    // Remove the default filter that adds <p> tags to category descriptions
    remove_filter( 'term_description', 'wpautop' );
    
    // Enqueue JavaScript for read more/read less functionality
    function enqueue_read_more_script() {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'read-more-script', get_stylesheet_directory_uri() . '/js/read-more.js', array( 'jquery' ), '1.0', true );
    }
    add_action( 'wp_enqueue_scripts', 'enqueue_read_more_script' );
    

    SOLUTION 2 - More complicated

    Override the template templates/archive-product.php located in the Woocommerce plugin or github re-create the file in your child theme as follows,

    Replace

    ?>
    <header class="woocommerce-products-header">
        <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?>
            <h1 class="woocommerce-products-header__title page-title"><?php woocommerce_page_title(); ?></h1>
        <?php endif; ?>
    
        <?php
        /**
         * Hook: woocommerce_archive_description.
         *
         * @hooked woocommerce_taxonomy_archive_description - 10
         * @hooked woocommerce_product_archive_description - 10
         */
        do_action( 'woocommerce_archive_description' );
        ?>
    </header>
    <?php
    

    with

    ?>
    <header class="woocommerce-products-header">
        <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?>
            <h1 class="woocommerce-products-header__title page-title"><?php woocommerce_page_title(); ?></h1>
        <?php endif; ?>
    
        <?php
        /**
         * Custom Hook: woocommerce_custom_archive_description.
         *
         * @hooked woocommerce_taxonomy_archive_description - 10
         * @hooked woocommerce_product_archive_description - 10
         */
        do_action( 'woocommerce_custom_archive_description' );
        ?>
    </header>
    <?php
    

    Then in the functions file add the following

            // Allow HTML in term (category, tag) descriptions
    foreach ( array( 'pre_term_description' ) as $filter ) {
        remove_filter( $filter, 'wp_filter_kses' );
        if ( ! current_user_can( 'unfiltered_html' ) ) {
            add_filter( $filter, 'wp_filter_post_kses' );
        }
    }
     
    foreach ( array( 'term_description' ) as $filter ) {
        remove_filter( $filter, 'wp_kses_data' );
    }
    // Remove the default filter that adds <p> tags to category descriptions
    remove_filter( 'term_description', 'wpautop' );
    
    // Enqueue JavaScript for read more/read less functionality
    function enqueue_read_more_script() {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_script( 'read-more-script', get_stylesheet_directory_uri() . '/js/read-more.js', array( 'jquery' ), '1.0', true );
    }
    add_action( 'wp_enqueue_scripts', 'enqueue_read_more_script' );
    
    
    // Modify the category description output
    function woocommerce_taxonomy_archive_description() {
        if ( is_product_category() ) {
            $term_id = get_queried_object_id();
            $description = get_term_field( 'description', $term_id, 'product_cat' );
    
            // Display the term description with the necessary HTML structure and IDs
            echo '<div>' . wpautop( $description ) . '<span id="dots"></span><span id="more">' . $description . '</span><span onclick="myFunction()" id="myBtn">Read more</span></div>';
        }
    }
    

    Create the following js file in the child theme /js/read-more.js

    jQuery(document).ready(function($) {
      function myFunction() {
        var dots = $("#dots");
        var moreText = $("#more");
        var btnText = $("#myBtn");
    
        if (dots.css("display") === "none") {
          dots.css("display", "inline");
          btnText.text("Read more");
          moreText.css("display", "none");
        } else {
          dots.css("display", "none");
          btnText.text("Close Biography");
          moreText.css("display", "inline");
        }
      }
    
      $("#myBtn").on("click", myFunction);
    });
    

    USAGE FOR BOTH SOLUTIONS

    in the css file add

    #more {display:none;}
    

    and to use in the product category description use as follows,

    Lorem Ipsum is simply dummy text of the printing and typesetting industry. <span id="dots"></span><span id="more">
    It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
    </span>
    
    <span onclick="myFunction()" id="myBtn">Read more</span>
    

  2. You can delegate the click event in your Javascript like so

    const el = document.getElementById("myBtn");
    el.addEventListener("click", myFunction);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search