1

I have an div with same class in a page, I have to go through each element in that div and see the text length, if the text length exceeds suppose 300. I have to hide/remove other elements and show the remaining elements.

check this fiddle

var x = 0

$(".updatedText").each(function(index, item) {
var self = $(this);

self.children().each(function(index, item){
    // self; parent li
    // this; child li
    //console.log( index + ": " + $(this).text());
    //console.log(isLastElement);
    if(x >= 100) {
        //$(this).text("");
        var y = x - 100;
        $(item).prev().text($(item).prev().text().substring(0,y));
        $(item).prev().append("....");
        $(this).remove();
        if(index == 0) {
            x = 0;
        }
    } else {
        x = x + $(this).text().length;
    }
});
});

Updated: I am able to limit the number of characters in each div without losing HTML elements. But I am not able to fix the number of characters each div should have.

Right now they are limiting the amount of text but the total text length varies. How can I make it exact 300 characters?

Note: I should not loose any HTML when limiting text. Updated Fiddle also.

Veer
  • 166
  • 1
  • 1
  • 16
  • 1
    Bit hard to tell what you're trying to achieve, but `$(".class *")` will pick all the children, children-children and children-children-children etc and loop through each of them - the first child.text() will contain all of its child-child .text() values as well - add a `console.log(x, $(item).text())` to see what each iteration is looking at. It could be that you need `$(".updatedText>*")` or that your `.updatedText` is in the wrong place (appears to be including menu items). So by the time it hits the 2nd, it's already > 300 (as shown with basic debugging) https://jsfiddle.net/x6cpkmb9/ – freedomn-m Jul 17 '20 at 11:14
  • Do you really want it to stop rendering the text inside DIVs when the running total length is > 300? – Nathan Champion Jul 17 '20 at 11:27
  • Yes i have to do nested each because I am getting index as , 1, 2, 3, 4 5 6 so on. I have updated the code. – Veer Jul 17 '20 at 11:29
  • @NathanChampion Yes, will be showing on click of a button in a popup. – Veer Jul 17 '20 at 11:33
  • RE: the edited note *I should not loose any HTML when limiting text* - then you simply can't use `.text("")` - instead use `$(this).hide()` or some other way to hide the text. – freedomn-m Jul 17 '20 at 11:36
  • Try to make a working example in the snippet. – SilverSurfer Jul 17 '20 at 11:36
  • Then you'd want to retain that text somewhere I would imagine via span, floating div, simply hiding the element ... something. The alternative would be along the lines of AJAX calls which seems redundant if you're serving up all the data initially. – Nathan Champion Jul 17 '20 at 11:37
  • I have updated question and fiddle. Please check once. – Veer Jul 17 '20 at 12:43
  • I have to retain HTML structure and limit number of characters in each div. – Veer Jul 17 '20 at 12:44
  • `$(".updatedText").each(function(index, item) { if ($(this).children().length > 0) return; ` – freedomn-m Jul 17 '20 at 14:10

1 Answers1

2

CSS

You can use CSS text-overflow property but it doesn't exactly truncate at length of 300.

.updatedText {
  line-height: 1em;
  max-height: 2em;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
<b>Div</b>
<div class="updatedText">
  I have an div with same class in a page, I have to go through each element in that div and see the text length, if the text length exceeds suppose 300. I have to hide/remove other elements and show the remaining elements. Updated: I am able to limit the
  number of characters in each div without losing HTML elements. But I am not able to fix the number of characters each div should have. Right now they are limiting the amount of text but the total text length varies. How can I make it exact 300 characters?
  Note: I should not loose any HTML when limiting text. Updated Fiddle also.
</div>

<br/>
<br/>

<b>Nested Div</b>
<div class="updatedText">
  <div>I have an div with same class in a page, I have to go through each element in that div and see the text length, if the text length exceeds suppose 300. I have to hide/remove other elements and show the remaining elements. Updated: I am able to limit</div>
  <div>the number of characters in each div without losing HTML elements. But I am not able to fix the number of characters each div should have.</div>

  <div>Right now they are limiting the amount of text but the total text length varies. How can I make it exact 300 characters?</div>

  <div>Note: I should not loose any HTML when limiting text. Updated Fiddle also.</div>
</div>

jQuery

Here I'm wrapping text nodes that exceed the truncate length with a span. And hiding the span using CSS display property to prevent losing HTML elements.

Reference

const TRUC_LENGTH = 300;

$(".updatedText").each(function() {
  // get all text nodes
  var textNodes = textNodesUnder(this)

  var total = 0
  textNodes.forEach(function(textNode) {
    let length = textNode.textContent.length
    
    if (total > TRUC_LENGTH) { // text nodes after TRUC_LENGTH
      $(textNode).wrap('<span class="overflow"/>')
    } else if (total + length > TRUC_LENGTH) { // text nodes in TRUC_LENGTH
      let left = textNode.textContent.substring(0, TRUC_LENGTH - total)
      let right = textNode.textContent.substring(TRUC_LENGTH - total)
      $(textNode).replaceWith(
        left + 
        '<span class="elipsis">...</span>' +
        '<span class="overflow">' + right + '</span>'
      )
    }
    total += length
  })

});

function textNodesUnder(el) {
  var n, a = [],
    walk = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, null, false);
  while (n = walk.nextNode()) a.push(n);
  return a;
}

$('button').on('click', function () {
  $(".updatedText").toggleClass("truncate")
})
.updatedText.truncate .overflow {
  display: none;
} 

.updatedText:not(.truncate) .elipsis {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<button>Toggle</button>
<br/>

<b>Div</b>
<div class="updatedText">
  I have an div with same class in a page, I have to go through each element in that div and see the text length, if the text length exceeds suppose 300. I have to hide/remove other elements and show the remaining elements. Updated: I am able to limit the
  number of characters in each div without losing HTML elements. But I am not able to fix the number of characters each div should have. Right now they are limiting the amount of text but the total text length varies. How can I make it exact 300 characters?
  Note: I should not loose any HTML when limiting text. Updated Fiddle also.
</div>

<br/>
<br/>

<b>Nested Div</b>
<div class="updatedText">
  <div>I have an div with same class in a page, I have to go through each element in that div and see the text length, if the text length exceeds suppose 300. I have to hide/remove other elements and show the remaining elements. Updated: I am able to limit</div>
    <div>the number of characters in each div without losing HTML elements. But I am not able to fix the number of characters each div should have.</div>

  <div>Right now they are limiting the amount of text but the total text length varies. How can I make it exact 300 characters?</div>

  <div>Note: I should not loose any HTML when limiting text. Updated Fiddle also.</div>
</div>

Note: text length includes the multiple spaces which are not rendered in html

User863
  • 19,346
  • 2
  • 17
  • 41