Discover the joy of reading with wrap/unwrap to consume more content in less

I am experimenting with a 'read-more read-less' feature using a wrap method that currently only works for the 'show more' functionality.
So, to clarify, if the text exceeds a certain length, I truncate it and insert a read-more-link (which is functional). Once expanded, I include a read-less-link intended to revert the text back to its original length for subsequent expansion with the read-more-link, but unfortunately, the wrapping does not function as expected.

$(document).ready(function() {
  var maxLength = 490;
  $(".keimeno").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 + ' <a href="javascript:void(0);" class="read-less">read less</a>' + '</span>');
    }
  });
  
  $(".read-more").click(function() {
    $(this).siblings(".more-text").contents().unwrap();
    $(this).remove();
  });
  
  $(".read-less").click(function() {
    $(this).remove();
    $(this).siblings(".more-text").contents().wrap();
  });
});
.keimeno .more-text {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExL3Og8ifwB6" crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Spicy+Rice&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3 Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous" />

<div class="card">
  <ul id="kirio">
    <li>
      <div class="col-lg-12">
        <p class="keimeno">
          SOME TEXT asdasdas SOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdas SOME TEXT asdasdas(SOME MORE TEXT...)
        </p>
      </div>
    </li>
    <li>
      <div class="col-lg-12">
        <p class="keimeno">
          SOME TEXT asdasdas SOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdas SOME TEXT asdasdas(SOME MORE TEXT...)
        </p>
      </div>
    </li>
  </ul>
</div>
jsfiddle: https://jsfiddle.net/b9nsmyvu/1/

Answer №1

If you want to streamline the text manipulation in your $(document).ready(); function, consider creating a separate function for it and then calling that function when the "read less" option is clicked. Remember to use event delegation with the click() events for both "read more" and "read less" on a static parent element like document, as these elements are dynamically added to the page.

$(document).ready(function() {
  function readMore() {
    var maxLength = 490;
    $(".keimeno").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 + ' <a href="javascript:void(0);" class="read-less">read less</a>' + '</span>');
      }
    });

  }
  readMore();
  $(document).on("click", ".read-more", function() {
    $(this).siblings(".more-text").contents().unwrap();
    $(this).remove();
  });

  $(document).on("click", ".read-less", function() {
    $(this).remove();
    readMore();
  });
});
.keimeno .more-text {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">
  <ul id="kirio">
    <li>

      <div class="col-lg-12">
        <p class="keimeno">
          SOME TEXT asdasdas SOME TEXT ... (remaining content truncated)
        </p>
      </div>

    </li>
    <li>

      <div class="col-lg-12">
        <p class="keimeno">
          SOME TEXT asdasdas SOME TEXT ... (remaining content truncated)
        </p>
      </div>

    </li>

  </ul>
</div>

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

Exploring the functions of JointJS within a Node.js environment

I am a beginner in using JavaScript, JointJS, and Node.js. I am currently working on a Node.js project in WebStorm, and the file structure looks like this: /test /bin www /node_modules /public /routes index.js users.js /views error.jade ...

Tips for saving data in a database using Ajax with ExtJS?

In my current project, I have a set of items displayed in a row-wise order in the view using JavaScript. My goal is to implement an auto-save feature that will save the details of the clicked rows into a database using AJAX within ExtJS. ...

Access information from Google Sheets through an AJAX GET request

I am facing an issue with my code while trying to retrieve data from a Google spreadsheet that I have already published. I have set the share properties of the spreadsheet to 'anyone can edit' and provided the correct URL, but I am still encounte ...

Unable to convert JavaScript object to C# through deserialization

In order to pass a model from the controller action to the view, I included a list of objects and converted it into a JavaScript object to facilitate displaying markers on Google Maps. My goal is to send the selected object (selected marker) back to the co ...

What are the steps to resolve issues with URL Encoding?

Here is my website link: forumdisplay.php?462-%EE%F9%E7%F7%E9%ED-%E1%F8%F9%FA I suspect that the url is URL Encoded. I am using vbulletin 4.1.12 How can I resolve this issue? Replace 462-%EE%F9%E7%F7%E9%ED-%E1%F8%F9%FA with f=462 ...

Converting multiple rows of data from MySQL into JSON format

Currently, I am working on a project that involves displaying multiple rows of MySQL JSON data in an HTML table using PHP and jQuery. The process includes input from a search box on the front end. The layout of my HTML table on the search page is structur ...

Is Jquery Mobile's Table lacking responsiveness?

I have implemented a basic table from the jQuery Mobile website on my page. Take a look at the HTML code below: <div data-role="page" id="mainPage"> <div data-role="content> <table data-role="table" id="my-table" da ...

Conversation with form component in angular2

I am currently using ng2-bootstrap-modal. For adding a sample form to the example Confirm Dialog, check out ng2-bootstrap-modal. To change the template: <div class="modal-dialog"> <div class="modal-content"> <form [formGroup]="login ...

What could be causing the AngularUI bootstrap datepicker to not appear?

Exploring the popup datepicker demo from angularUI bootstrap, which is embedded in their page and works perfectly. However, when I tried to create a minimal plunker here, the button click does not open the calendar. Any thoughts on what might be causing th ...

"Which is better for handling form data: using $.ajax with hidden fields or PHP form

Creating a streamlined admin tool using PHP and JQuery to handle image data management is my current project. The main goal of this utility is to enable an admin to retrieve images from a database, view associated tags for each image, and add new tags as n ...

Customize your QTabBar icons with Qt Stylesheet: Adjusting the icon mode

I am currently working on customizing a QTabBar with a stylesheet in my tool. I use QIcon to create icons for the tabs, allowing me to set different modes such as normal, disabled, and selected. The challenge I am facing is trying to apply a global stylesh ...

Received the error 'Headers cannot be set after they have been sent to the client' upon the second request

I created a web server that acts as a client-side application using socket.io-client and express. This setup is necessary for another project I am working on. The web server emits the posted string and responds by sending the served string when it receive ...

There was an issue with the origin null not being permitted by Access-Control-Allow-Origin

Possible Duplicate: XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin I am currently working on a weather application that runs smoothly in browsers. However, when I try to deploy it on my Android phone, it encounters iss ...

Incorporating Sass into an HTML document

Recently, I discovered Sass and went through its documentation. I successfully installed the package on my Ubuntu system alongside Ruby and Haml. Now I'm eager to learn how to use it with Wordpress or a basic HTML file. Being new to this, I'm see ...

Angular's input event fails to trigger for dynamically generated fields when pasted into them

When working with a form that has dynamically generated input fields, I encountered an issue. I needed to display a preview of the input contents on a div while pasting content into the fields. This project is built using Angular 11. Below is my .ts file: ...

The counter unexpectedly increments by 2 instead of 1

I'm attempting to create a counter that increases by one each time according to the code snippet below: var imnum = 0; (function changeImage() { ++imnum; $( ".slider" ).fadeOut(5000, function() { $('#home-slider-im').attr("s ...

Updating the head() properties in Nuxt.js via asyncData() is not possible

After creating a server-side rendered Vue.js blog with Nuxt.js using Typescript and Ghost, I encountered a problem updating html metatags with data from asyncData(). According to the Nuxt.js documentation, asyncData() is triggered before loading page comp ...

Setting up ESLint for TypeScript with JSX configuration

I am encountering problems with TypeScript configuration. Below is the code snippet from my tsconfig.json: { "compilerOptions": { "target": "es5", "lib": [ "dom", "dom.iterable", "esnext" ], "allowJs": true, "skipLib ...

Avoiding the duplication of selected items in a dropdown within a gridview can be achieved effectively by implementing a JavaScript/jQuery

In my gridview, which contains multiple rows, each row has a dropdown (select in HTML). My goal is to prevent the user from selecting the same item from the dropdown list for different rows. For instance, if a user selects "New York": Assigning rooms: U ...

Changing the name of a React Native sample application

I am currently working on a project based on this App example: https://github.com/aksonov/react-native-router-flux/tree/master/Example When I tried to change the following lines: index.ios.js import App from './App'; AppRegistry.regist ...