Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

append "show more" link to truncated paragraph only if set amount of characters is met

I want to append the "show more" link (if clicked will reveal the content that has been trimmed/hidden) to my paragraph only if the X amount of characters are passed.

For example I set the minimum to 120 chars, and the paragraph has only 60 therefore I dont need to append the "show more" link.

How Can I solve it? The code below works great but will apply "show more" to any paragraph I have even though is less then the X amount.. What should I do?

https://jsfiddle.net/vm0uj7fc/1/

    var charLimit = 122;

function truncate(el) {
  var clone = el.children().first(),
      originalContent = el.html(),
      text = clone.text();
  el.attr("data-originalContent", originalContent);
  clone.text(text.substring(0, charLimit) + "...")
  el.empty().append(clone);
}

function reveal(el) {
  el.html(el.attr("data-originalContent"));
}

$("a").on("click", function (e) {
  e.preventDefault();
  var truncateElement = $(this).parent().prev().find(".truncate");
  if ($(this).text() === "Read More") {
      $(this).text("Read Less");
      reveal(truncateElement);
  } else {
      $(this).text("Read More");
      truncate(truncateElement);
  }
});

$(".truncate").each(function () {
    truncate($(this));
});

to recap:

  • I need to append the "read more" dynamically with (.append function?)
  • Check the chars and if less then the max amount do NOT show read more
  • optional, if someone can come up with pure Javascript that would be the preferred choice if not I'm ok with some code refactoring starting from my code above
like image 282
user2513846 Avatar asked May 17 '16 04:05

user2513846


2 Answers

I write a pure javascript that handle your request, see the demo here: https://jsfiddle.net/IA7medd/751sLn0n/

HTML:

<div class="container">
      <div class="events-left-col">
        <h2 class="eventTitle">Event Title</h2>
          <div class="wrap">
            <div class="truncate">
              <p class="toggledText">
                  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod 
                  tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, 
                  quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo 
                  consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie 
                  consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto 
                  odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait 
                  nulla facilisi.
              </p>
            </div>
          </div>

          <div class="wrap">
            <div class="truncate">
              <p class="toggledText">
                  Not enough characters here to show/append the "Read more" link
              </p>

            </div>
          </div>

           <div class="wrap">
            <div class="truncate">
              <p class="toggledText">
                  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod 
                  tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, 
                  quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo 
                  consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie 
                  consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto 
                  odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait 
                  nulla facilisi.
              </p>
            </div>
          </div>


        </div>
      </div>

style:

.toggledText span.trimmed{
  display:none;
}
.read-more .more:before{
  content:'Read More';
}
.showAll .toggledText span.morePoints{
  display:none;
}
.showAll .toggledText span.trimmed{
  display:inline;
}
.showAll .read-more .more:before{
  content:'Read Less';
}

script:

var charLimit = 120;

        var numberOfToggled = document.getElementsByClassName('toggledText');
        for(i=0; i<numberOfToggled.length; i++){

            var el = numberOfToggled[i];
            var elText = el.innerHTML.trim();

            if(elText.length > charLimit){
                var showStr = elText.slice(0,charLimit);
                var hideStr = elText.slice(charLimit);
                el.innerHTML = showStr + '<span class="morePoints">...</span> <span class="trimmed">' + hideStr + '</span>';
                el.parentElement.innerHTML = el.parentElement.innerHTML + "<div class='read-more'><a href='#' class='more'></a>";
            }

        }

        window.onclick = function(event) {
            if (event.target.className == 'more') {
                event.preventDefault();
                event.target.parentElement.parentElement.classList.toggle('showAll');

            }
        }

I also made some edits on your code and it work fine. you can see it here: https://jsfiddle.net/IA7medd/j78L76qj/ ( if you nedd it )

like image 140
Ahmed Salama Avatar answered Oct 29 '22 20:10

Ahmed Salama


I have make some changes in your code.I have listed down the approch which me help you to understand

  1. Iterate through each .truncate
  2. Check if total character length is more than 122;
  3. If true remove the class normHeight & add class modHeight
  4. On click of the link remove the modHeight & add class 'normHeight'

This below snippet can be useful

var charLimit = 122;
function _truncate(el) {
      var _clone = el.children().first();
       //Removing white space & checking length
        // _clone[0] because _clone is array of jquery object
        if(_clone[0].innerHTML.trim().length>charLimit){  
           _clone.removeClass('normHeight').addClass('modHeight');
         //Appending read me link
          el.append($("<div class='read-more'><a href='#' class='more'>Read More</a>"));
       }
    }

    // Since a.more is dynamic element so using event delegation.
    $("body").on("click",'a.more',function (e) {
      e.preventDefault();
      $(this).parent().siblings('p.modHeight').removeClass('modHeight').addClass('normHeight');
      $(this).hide(); // Once entire text is visible remove read me link
    });

    $(".truncate").each(function () {
        _truncate($(this));
    });

Also note the minor change in HTML and CSS

Check this jsfiddle for demo

like image 30
brk Avatar answered Oct 29 '22 22:10

brk