Search code examples
javascripthtmljquerycssshow-hide

Read more read less with wrap/unwrap


I am trying to make a 'read-more read-less' with a wrap method but it only works for show more.
So basically if the text is longer than I need it to be I strip it and add a read-more-link (that works). After it is unstripped I add a read-less-link that is supposed to strip it to its previous length so it can be unstripped again with the read-more-link but wrap doesn't work here.

$(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 asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
          TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE
          TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MORE
        </p>
      </div>
    </li>
    <li>
      <div class="col-lg-12">
        <p class="keimeno">
          SOME TEXT asdasdas SOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
          TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
          TEXT asdasdas
        </p>
      </div>
    </li>
  </ul>
</div>
jsfiddle: https://jsfiddle.net/b9nsmyvu/1/


Solution

  • You can make a function out of the text manipulaton that you do on $(document).ready(); and call that function when "read less" is clicked. Also note that it's necessary to delegate the click() events for "read more" and "read less" from a static parent element like document as both are added dynamically 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 asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
              TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE
              TEXT MOREOME TEXT MORE TEXT MOREOME TEXT MORE TEXT MORE
            </p>
          </div>
    
    
    
        </li>
        <li>
    
          <div class="col-lg-12">
            <p class="keimeno">
              SOME TEXT asdasdas SOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
              TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME TEXT asdasdasSOME
              TEXT asdasdas
            </p>
          </div>
    
    
        </li>
    
      </ul>
    </div>