2

I get a posts from an API and I get the post content as a string HTML, and I need to show read more button if the content is more than 1000 characters.

here is an example of the text.

enter image description here

How I can manage to do this?

Amar Singh
  • 5,464
  • 2
  • 26
  • 55

4 Answers4

14

Update: Adding code snippet to run and add support handle the HTML string.

Use it like <SmartText text={'what ever'} length={30} />. length is limit to show the 'View more' link.

const SmartText = ({ text, length = 20 }) => {
  const [showLess, setShowLess] = React.useState(true);

  if (text.length < length) {
    return <p>{text}</p>;
  }

  return (
    <div>
      <p
        dangerouslySetInnerHTML={{
          __html: showLess ? `${text.slice(0, length)}...` : text,
        }}
      ></p>
      <a
        style={{ color: "blue", cursor: "pointer" }}
        onClick={() => setShowLess(!showLess)}
      >
        &nbsp;View {showLess ? "More" : "Less"}
      </a>
    </div>
  );
};

const htmlText =
  "<a> Hello Lorem Ipsum is <strong> simply dummy </strong> text of the printing and </a> typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

ReactDOM.render(<SmartText text={htmlText} />, document.getElementById("app"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="app"></div>

If the contents are only text (no HTML string)

const SmartText = ({ text, length = 20 }) => {
  const [showLess, setShowLess] = React.useState(true);

  if (text.length < length) {
    return <p>{text}</p>;
  }

  return (
    <div>
      <p>{ showLess ? `${text.slice(0, length)}...` : text }</p>
      <a
        style={{ color: "blue", cursor: "pointer" }}
        onClick={() => setShowLess(!showLess)}
      >
        &nbsp;View {showLess ? "More" : "Less"}
      </a>
    </div>
  );
};

const text =
  "Lorem Ipsum is text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.";

ReactDOM.render(<SmartText text={text} />, document.getElementById("app"));
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="app"></div>
Siva K V
  • 10,561
  • 2
  • 16
  • 29
  • Thanks for answering, but this will not work if you saw the attached image you will see that my text isn't a plain text is a stringified HTML, that's mean if I used your solution it will consider the HTML tags and it's data like class and data-type, etc. as a text. – Muhammed Mushtaha Jan 30 '20 at 09:53
  • @MuhammedMushtaha, Ok, I see. I think you can slightly change the above component to 'render HTML string', some thing like https://stackoverflow.com/questions/39758136/render-html-string-as-real-html-in-a-react-component. – Siva K V Jan 30 '20 at 10:03
  • @MuhammedMushtaha, Updated the answer to support the HTML string. – Siva K V Dec 15 '20 at 07:18
1

You can run this code snippet.

const fullText = "Living valley had silent eat merits esteem bed. In last an or went wise as left. Visited civilly am demesne so colonel he calling. So unreserved do interested increasing sentiments. Vanity day giving points within six not law. Few impression difficulty his use has comparison decisively. Not far stuff she think the jokes. Going as by do known noise he wrote round leave. Warmly put branch people narrow see. Winding its waiting yet parlors married own feeling. Marry fruit do spite jokes an times. Whether at it unknown warrant herself winding if. Him same none name sake had post love. An busy feel form hand am up help. Parties it brother amongst an fortune of. Twenty behind wicket why age now itself ten."

function showMore(){
  document.getElementById('text-body').innerHTML =  fullText;
  document.getElementById('btn-show-less').style="display:block";
  document.getElementById('btn-show-more').style="display:none";
}

function showLess(){
  document.getElementById('text-body').innerHTML = "partial text..." 
  document.getElementById('btn-show-more').style="display:block";
  document.getElementById('btn-show-less').style="display:none";
}
<div id="text-body">
  partial text...
</div>
<button id="btn-show-more" onClick='showMore()'>read more</button>
<button id="btn-show-less" style="display:none" onClick='showLess()'>show less</button>
rudresh solanki
  • 925
  • 9
  • 4
0

I hope this works for you

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#more {display: none;}
</style>
</head>
<body>

<h2>Read More Read Less Button</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction()" id="myBtn">Read more</button>

<script>
function myFunction() {
  var dots = document.getElementById("dots");
  var moreText = document.getElementById("more");
  var btnText = document.getElementById("myBtn");

  if (dots.style.display === "none") {
    dots.style.display = "inline";
    btnText.innerHTML = "Read more"; 
    moreText.style.display = "none";
  } else {
    dots.style.display = "none";
    btnText.innerHTML = "Read less"; 
    moreText.style.display = "inline";
  }
}
</script>

</body>
</html>
Engineer S. Saad
  • 378
  • 4
  • 19
0

You can use only the height of the container and use a showMore state

  const [showMore, setShowMore] = useState(false);


<div
  className={classNames('description-box', showMore ? 'show-content' : 'hide-content')}>
  <Editor
    value={editable}
    displayOnly
  />
  <Button onClick={() => setShowMore(!showMore)}>{showMore ? t('showLess') : t('showMore')}</Button>
</div>

By default your container will have hide-content class with the height that you want and on showMore, will switch to height:auto

.hide-content{
  height: 300px;
  overflow: hidden;
}

.show-content{
  height: auto;
}
  • If you have a new question, please ask it by clicking the [Ask Question](https://stackoverflow.com/questions/ask) button. Include a link to this question if it helps provide context. - [From Review](/review/late-answers/31203284) – Francisco Puga Mar 07 '22 at 10:11