Instructions for showing a "read more" and "read less" link when the text goes beyond a

I am pulling paragraph content from the database and displaying only 300 characters on the screen, with a "read more" option for the user to see the rest of the content.

However, I am facing an issue where I also need to include a "less" option for the user to revert back to the truncated version of the content after clicking on "read more." I have attempted the following code snippet:

$(document).ready(function() {
  var maxLength = 300;
  $(".countParawords").each(function() {
    var myStr = $(this).text();
    if ($.trim(myStr).length > maxLength) {
      var newStr = myStr.substring(0, maxLength);
      var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
      $(this).empty().html(newStr);
      $(this).append(' <a href="javascript:void(0);" class="read-more">...READ MORE</a>');
      $(this).append('<span class="more-text">' + removedStr + '</span>');
    }
  });
  $(".read-more").click(function() {
    $('.less').show();
    $(this).append(' <a href="javascript:void(0);" class="less">LESS</a>');
    $(this).siblings(".more-text").contents().unwrap();
    $(this).remove();

  });
  $(".less").click(function() {
    $(this).siblings(".more-text").contents().wrap();
    $(this).remove();
  });
});
.box {
  width: 500px;
  margin: auto;
}

.box .more-text {
  display: none;
}

.box .less {
  display: none;
}
<div class="box">
  <p class="countParawords">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing
    elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit essecillum
    dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

Answer №1

I've made a few modifications to your JavaScript code to ensure it functions correctly. Please give this a try:

$(document).ready(function() {
  var maxLength = 300;
  var moretxt = "...Show More";
  var lesstxt = "...Show Less";
  $(".countParawords").each(function() {
    var myStr = $(this).text();
    if ($.trim(myStr).length > maxLength) {
      var newStr = myStr.substring(0, maxLength);
      var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
      $(this).empty().html(newStr);
      $(this).append('<span class="more-text">' + removedStr + '</span>');
      $(this).append(' <a href="javascript:void(0);" class="read-more more">' + moretxt + '</a>');
    }
  });
  $(".read-more").click(function() {
    if($(this).hasClass("more")){
        $(this).removeClass("more");
        $(this).text(lesstxt);
        $(this).siblings(".more-text").show();
    }
    else {
        $(this).addClass("more");
        $(this).text(moretxt);
        $(this).siblings(".more-text").hide();
    }

  });

});
.box {
  width: 500px;
  margin: auto;
}

.box .more-text {
  display: none;
}

.box .less {
  display: none;
}
<div class="box">
  <p class="countParawords">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing
    elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit essecillum
    dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

Give it a try and let me know if you need further assistance.

Answer №2

Altered the code to make it functional, incorporating a few adjustments which will be elaborated within the code itself.

$(document).ready(function() {
  var maxLength = 300;
  var readMore = null;
  $(".countParawords").each(function() {
    var myStr = $(this).text();
    if ($.trim(myStr).length > maxLength) {
      var newStr = myStr.substring(0, maxLength);
      var removedStr = myStr.substring(maxLength, $.trim(myStr).length);
      $(this).empty().html(newStr);
      $(this).append(' <a href="javascript:void(0);" class="read-more">...READ MORE</a>');
      $(this).append('<span class="more-text">' + removedStr + '</span>');
      // Storing the content in a global variable as removing the element from the DOM removes its content
      readMore = $(this).find(".more-text").contents();
    }
  });
  $(".read-more").click(function() {
    // Targeting the parent element to hide the content as this element will be hidden
    $(this).parent().append(' <a href="javascript:void(0);" class="less">LESS</a>');
    $(this).siblings(".more-text").contents().unwrap();
    $('.less').show();
    $(this).hide();
    
    // Adding click listener inside the read more click listener as the element is created post clicking read more
    var parentThis = this;
    // Storing parent "this ref" in a variable to remove the less element
    $(".less").click(function() {
      // Wrapping the previously stored content in span
      readMore.wrap('<span class="more-text"></span>');
      // Making read more visible
      $(parentThis).show();
      // Removing the less element
      $(this).remove();
    });

  });
});
.box {
  width: 500px;
  margin: auto;
}

.box .more-text {
  display: none;
}

.box .less {
  display: none;
}
<div class="box">
  <p class="countParawords">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure
    dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing
    elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit essecillum
    dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</div>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>

Kindly go through the comments scattered throughout the code

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with data binding in AngularJS when using the input element

I am encountering an issue with my AngularJS code. When I try to input text into the textbox, it is not appearing in the binding. <!DOCTYPE html> <html lang="en"> <head> <script src="js/angular.js"></script> <scr ...

Issues have been raised with IE11's refusal to accept string(variable) as a parameter for the localStorage

Why is it that Internet Explorer does not recognize a string variable as a parameter for the setItem method, even though it works fine in Chrome? For example, in IE: This code snippet works: var itemName = 'anyname'; localStorage.setItem(itemN ...

Exploring React-Query's Search Feature

Looking for guidance on optimizing my Product search implementation using react-query. The current solution is functional but could be streamlined. Any suggestions on simplifying this with react-query would be greatly appreciated. import { useEffect, use ...

Ways to center a vertically aligned SVG in relation to text using Bootstrap

After experimenting with bootstrap, I have encountered an issue where I cannot vertically center an inline SVG relative to text. Below is a simplified example showcasing this problem: <!DOCTYPE html> <html> <head> <link rel=& ...

Can Chrome Support Bookmarklets?

While attempting to craft a bookmarklet in Chrome using the console, I encountered the following error: Refused to load the script 'https://code.jquery.com/jquery-1.6.1.min.js' because it violates the following Content Security Policy directive: ...

Listening to audio on a mobile browser using an HTML audio element

What is the solution for the problem of playing audio on a mobile browser when it plays on a desktop browser but not on mobile? The code being used is: var audio = new Audio('sound.mp4') audio.play() ...

Incorrect comparison of floats within arrays resulted in inaccurate results

I am currently working on a project that involves comparing values in an Array which are dynamically fetched from a website, and I'm using Selenium-IDE to assist with this comparison. However, I've noticed that the values are being compared as s ...

Can the :after pseudo-element be modified when hovering, except when hovering over the after element itself?

Currently, my CSS code looks like this: class-name:hover:after {} Although it works well, the hover effect triggers even when hovering over the after portion of the element. Is there a way to modify the code so that the :hover only applies when hovering ...

Interactive webpages with dynamic HTML content, similar to the design of popular platforms such

Explore the source code of Dropbox's homepage or any Soundcloud page. They utilize various scripts and minimal pure HTML content (article, main, p, div). This method of generating pages is referred to as dynamic content/HTML. The main function seems ...

Encountered an error in React where the declaration file for a module could not be located

New to Typescript and trying to incorporate a splitter into my project. I'm utilizing SplitPane from "react-split-pane/lib/SplitPane" and Pane from "react-split-pane/lib/Pane" in my Typescript project, but encountering an error: Could not find a de ...

What is the best way to ensure type safety in a Promise using Typescript?

It seems that Promises in Typescript can be type-unsafe. This simple example demonstrates that the resolve function accepts undefined, while Promise.then infers the argument to be non-undefined: function f() { return new Promise<number>((resolve) ...

The reset function for the selector is failing to properly reset the data within the table

I need help with a selector that has multiple options and a reset button. When the reset button is clicked, it should reset the selector back to the first option. Although the selector resets as expected when the button is clicked, the data in the table r ...

A guide on deploying a Next.js application using Passenger

I'm completely new to development and I'm attempting to deploy my very first application (let's call it testing). I am looking to deploy my Next.js React app using Passenger (which is included and required by Dreamhost, so I have not insta ...

Retrieve the bounding rectangle of a div that has the CSS style `display: contents` using the getBoundingClientRect

My objective is to apply styling and obtain the bounding box of an entire "row" within a CSS grid, including features like highlighting when hovering over it. To achieve the styling aspect, I make use of the display: contents property, so that the styles ...

The increasing number of ajax requests is causing the page to become sluggish and unresponsive

Here is the ajax script that I am currently using: $.ajaxSetup ({ // Disable caching of AJAX responses cache: false }); function getRandomInt() { return Math.floor(Math.random() * Math.pow(10,6)); } $(document).ready(fu ...

Are there any reliable sources for a complete list of browser CSS properties?

Is there a way to easily access a comprehensive list of CSS properties supported by specific browsers, particularly IE8? Any suggestions on where I can find this information? ...

Adjust the position if the height exceeds 100 pixels

Can someone help with this code issue? $(document).ready(function () { if ($('.pi-img').height() > 100) { $(this).css('top' , '30%'); console.log('yeah'); } }); I am encountering difficu ...

Can a fixed div be made to adapt to different screen sizes?

Struggling to make SVG data charts responsive due to the 'position:fixed' CSS attribute applied, I'm exploring alternative solutions that don't involve media queries. Ideally, I want the SVG to scale up and down while remaining centered ...

Update the image source through an AJAX call

I've experimented with various methods to update an image src using an AJAX request. The new URL is obtained through the AJAX call, and when inspecting the data in Developer Tools, the 'DATA' variable contains the correct URL. However, the i ...

Using Vue.js data with an erb link_to tag

Currently, I am developing a Rails application where one page utilizes Vue.js to load a Google map, make some API calls with Axios, and gather user values using Vue.js. My goal is to pass these values as parameters within a "link_to" erb tag. Please refer ...