Is there a way to display only the first x characters of an HTML code while disregarding any tags present within

When I work with a text editor, it generates HTML code that I save in the database. On another page, I need to display only the first 100 characters of the text without counting the HTML tags.

For instance, let's say this is the HTML code saved in the database:

<p><span style="color:red; font-size:20px; font-family:Arial">
Here is the real text that I want to strip to 100 characters</span></p>
<p>Can be splited <b>between</b> multiple divs. 
Here is some more text to be longer <p>

If I try to use substring in JavaScript, it would end up breaking the HTML code like so:

<p><span style="color:red; font-size:20px; font-family:Arial">
Here is the real text that I want to s

But what I actually want is to achieve this result:

<p><span style="color:red; font-size:20px; font-family:Arial">
Here is the real text that I want to strip to 100 characters</span></p>
<p>Can be splited <b>between</b> multiple divs. 
H<p>

This project is developed using Angular 4, so any suggestions involving JS, Angular, CSS, HTML, or leveraging Node.js on the backend would be greatly appreciated.

Answer №1

When working on the frontend, you have the ability to achieve something similar to this:

var div=document.createElement("div");
div.innerHTML='<p><span style="color:red; font-size:20px; font-family:Arial">Here is the real text that I want to strip to 100 characters</span></p><p>Can be splited <b>between</b> multiple divs. Here is some more text to be longer <p>';
var excerpt=div.innerText.substring(0,100);
console.log(excerpt)

The variable excerpt will contain the first 100 characters.

Edit if you want to retain the HTML tags, you can utilize the following method:

var count = 0;

function strip(el, max) {
  var children = Array.prototype.slice.call(el.childNodes);
  children.forEach((node) => {
    if (node instanceof Text) {
      var newCount = count + node.textContent.length;
      var diff = newCount - max;
      if (diff > 0)
        node.textContent = node.textContent.substring(0, node.textContent.length - diff);
      count += node.textContent.length;
    } else if (node instanceof HTMLElement) {
      if (count >= max)
        node.remove(); // remove unnecessary tags
      else
        strip(node, max); // do recursively
    }
  })
}

var div = document.createElement("div");
div.innerHTML = '<p><span style="color:red; font-size:20px; font-family:Arial">Here is the real text that I want to strip to 100 characters</span></p><p>Can be splited <b>between</b> multiple divs. Here is some more text to be longer <p>'
var clone = div.cloneNode(true)
strip(clone, 100)
document.write("<h2>Original</h2>");
document.write(div.innerHTML);
document.write("<h2>Stripped</h2>");
document.write(clone.innerHTML);

It's important to note that the strip function will alter an existing HTMLElement, hence why it was cloned in this example.

If you wish to implement this server-side, a DOM parser for Node.js can be utilized with a similar approach.

Answer №2

If you're working with node.js, there is a useful package called htmlToText

var htmlToText = require('html-to-text');
var htmlText = '<p><span style="color:red; font-size:20px; font-
   family:Arial">Here is the real text that I want to strip to 100 characters</span></p>
   <p>Can be splited <b>between</b> multiple divs. 
   Here is some more text to be longer <p>';

var text_100firstNonHtml  = htmlToText.fromString(htmlText, {
    wordwrap: 130
}).substring(0,100);

console.log(text_100firstNonHtml);

Answer №3

Your backend is nodejs, so a convenient solution would be to remove all html tags on the server side and only send the text with a specified length to the client. You can utilize the "striptags" npm package for node. Check it out here: https://www.npmjs.com/package/striptags

Alternatively, using jQuery makes it simple (whether on the server or client side), but you have the freedom to choose any html parser/framework.

var htmlStr = '<p><span style="color:red; font-size:20px; font-family:Arial">Here is the real text that I want to strip to 100 characters aaaaa bbbbbb cccccc ddddd eeeeee ffff ggggg hhhh iiii jjjj kkk llllll mmmm nnnn</span></p><p>Can be splited <b>between</b> multiple divs. Here is some more text to be longer <p>';
var $html = $(htmlStr);

$html.find('*').each(function(idx, tag) {
  var shortText = $(tag).text().substring(0,100);
  $(tag).text(shortText);
});

console.log($html.html());
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Answer №4

Go through each child element's text content, identify the x-character position, and insert a special string (like '@@' in this example) to separate the text at that point (I set a limit of 70 characters for testing purposes):

var counter = 0;
var children = document.getElementById("test").children;
for (var i = 0; i < children.length; i++) {
  var node = children[i];
  var inText = node.textContent;
  if (counter + inText.length > 70) {
    var index = 70 - counter;
    node.textContent = inText.slice(0, index) + "@@" + inText.slice(index);
    break;
  } else {
    counter += inText.length;
  }
}
var index = document.getElementById("test").innerHTML.indexOf("@@");
var output = document.getElementById("test").innerHTML.substring(0,index);
alert(output);
<div id="test">
  <p><span style="color:red; font-size:20px; font-family:Arial">Here is the actual text that needs to be trimmed to 70 characters</span></p>
  <p>Can be split <b>across</b> multiple divs.H
    <p>
</div>

(you can also choose to remove the @@ marker afterwards)

Answer №5

When incorporating API response into an HTML file, a helpful approach is to utilize the following code:

{{response.string.slice(0,100)}}

This will effectively showcase only the initial 100 characters of your string.

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

The 600 pixel wide page is not completely filling the 640 pixel width screen on a mobile device

Currently, I am conducting a test on a webpage using an iPhone 5s with a screen resolution of 1136 x 640 pixels. The meta tag is set as follows: <meta name="viewport" content="user-scalable=yes, initial-scale=1, width=device-width, shrink-to-fit=no"&g ...

Is there a way to execute JavaScript code before any other scripts on the page? I need to perform a session check in JavaScript that redirects to a different page

My website has session and JavaScript checks to see if it exists. Everything is working correctly, but there is a slight issue where the dashboard page briefly appears for milliseconds before redirecting. I need the webpage to redirect before any HTML co ...

Navigating through Angular Material table elements

Currently, I am working with Angular Material's mat-table component and have noticed a unique notation used for loop properties such as *matCellDef, which is demonstrated in this Demo. In an attempt to streamline my code, I sought to dynamically gener ...

What is the best way to efficiently transmit Objects through AJAX utilizing bodyParser in node.js express?

Currently attempting to execute: $.ajax({ type:"POST", url:"/psychos", data:JSON.stringify(this.psycho) }) Upon reaching the server, I encounter the following: app.post("/psychos", function(request, respon ...

IE does not encode single quotes/apostrophes in URLs

Encountering an issue with an AJAX call using jQuery on IE11 specifically when the parameter contains a single quote or apostrophe. According to the jQuery documentation found at https://api.jquery.com/jquery.getjson/ Data sent to the server is added t ...

Navigating to a specific page based on the selected option is the key to efficient web browsing

I'm currently working on a form development project and I'm looking for guidance on how to navigate to different pages based on the selection made in a radio button. Here's the current form setup with two radio buttons: .sh_k .sh_sl { ...

Attempting to embed an image within the datepicker input

After successfully implementing the datepicker to select a date, I decided to add a buttonImage option for opening the datepicker on image click. However, I encountered an issue when trying to place my calendar image inside my input element, floated to th ...

Arrange three div elements beside each other with the middle column containing two

My challenge involves figuring out how to display 3 divs on a webpage in a specific layout. Currently, I am able to get 2 divs to align next to each other using the float:left property. However, the third div always ends up positioned below the first one ...

PHP - session expires upon page refresh

I'm in the process of creating a login system for my website and I've run into an issue with updating the navigation bar once a user has logged in. Every time I refresh the page, it seems like the session gets lost and the navigation bar doesn&ap ...

Affixing a navigation bar to the top while scrolling

Does anyone know how to create a navigation bar that will "dock" to the top of the browser when scrolled to, and undock when scrolled back up? Check out my code snippet here: http://jsfiddle.net/gLQtx/ $(function() { var initPos = $('#stickyNav&apo ...

Enhance the appearance of your forms with the "Bootstrap

I'm having trouble with the input-group-addon class. My HTML code is dynamically generated using JavaScript and follows the same structure across different pages. However, it works on one page but not on another. I can't seem to figure out why! ...

Creating a JSON structure using an array in Typescript

Here is an example of my array structure: [ { "detail": "item1", "status": "active", "data": "item1_data" }, { "detail": "item2", "status": ...

An easy way to ensure IE opens PDF links in an iframe in a new tab

I've encountered an issue while trying to display pdf files on an html page using an iframe. Here's my code snippet: <iframe src="testfile.pdf" width="100%" height="100%"></iframe> My problem is that the links within the pdf always ...

Enhancements in Converting JSON Objects to HTML Lists Using jQuery

I have created a function that converts a multi-dimensional JSON object into an HTML list. You can check it out here: http://jsfiddle.net/KcvG6/ Why is the function rendering the lists twice? Update: http://jsfiddle.net/KcvG6/2/ Are there any impro ...

Achieve a stunning visual effect by placing images behind the background using HTML and

I'm currently working on developing a webpage with a slideshow feature. I've decided that I want the transition between images in the slideshow to be a smooth fade effect, going from color to image to color. To achieve this, I have set up a backg ...

How can I prevent the jQuery animation from moving elements by adjusting the border?

I've been working on a small jQuery script that animates the border of images when hovered over. However, I've run into an issue with unwanted repositioning of adjacent images due to the border width increase. $(document).ready(function(e) { ...

"Upon setting the state in React, the Full Calendar refreshes and retrieves events

My current setup involves using the FullCalendar API to fetch events as shown below: <FullCalendar ref={calendarRef} plugins={[listPlugin, bootstrap5Plugin]} initialView='listMonth' ...

Menu options displayed with the help of HTML5 tags

Currently, I am experimenting with creating an interactive HTML5 dropdown menu in my spare time. While researching on W3Schools about dropdown menus, I noticed that all of them utilize CSS classes and id's for styling. This is a snippet of the HTML c ...

Tips for incorporating a return statement within a network request function that is already returning information pertaining to the request

Is there a way to retrieve the data extracted from within newReq.on('response', (response) => {? var request = require('request'); const cheerio = require('cheerio'); const { app, net, BrowserWindow } = require('elect ...

What is the best approach for managing validations on a field-by-field basis within a Formik FieldArray?

Scenario: When there are 3 participants, each participant will receive a set of questions. However, the display of each question is dependent on a list of "applied tickets" associated with the question. TLDR; I need to understand: if it's possible ...