Angular JS condensed text

Is it possible to implement AngularJS in order to extract a substring from a string and add an ellipsis at the end, while also being able to ignore anchor tags within the substring?

Let's consider the following example text:

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.

I want to display only the first 70 characters of the text followed by an ellipsis.

In some cases, there might be an anchor link within the portion of the text that needs to be substringed. If we simply cut off the text at 70 characters, it can result in a broken anchor link.

Currently, I am using the following HTML setup:

> data-ng-bind-html

to handle the substringing process.

Instead of relying on CSS with its limitations related to variable content length, I have implemented a custom filter called 'customEllipsis' which properly truncates the text without breaking any anchor tags:

filter('customEllipsis', function() {
        return function(input, number) {
            if (input) {
                return input.length > number ? input.substring(0, number) + '...' : input;
            }
        };
    });

Answer №1

Utilize the Angular sanitizer for HTML parsing. Take a look at this jsbin example to see it in action.

app.filter('customEllipsis', function($sce) {
  return function(input, number) {
    if (input) {
      input = input.length > number ? input.substring(0, number) + '...' : input;
      input = $sce.trustAsHtml(input);
      return input;
    }
  };
});

Answer №2

An effective way to manipulate data in Angular is by implementing the built-in filter called limitTo

Answer №3

This unique solution tackles the problem in a systematic way:

  1. Firstly, it converts the HTML content to a DOM document
  2. A depth-first traversal of the document is then carried out
  3. All text nodes are evaluated, truncated after reaching the maximum length, and an ellipsis is added
  4. Any remaining nodes that exceed the limit are discarded
  5. Finally, the result is serialized back to HTML format

The code snippet provided below includes the full implementation. An example demonstrates how a given string

Click <a href="http://stackoverflow.com">this absolutely <b>ah-mah-zing</b> link</a> to access Stackoverflow.

is limited to 20, 25, 30, 35, 40, 45, and 50 characters respectively.

Execute the code snippet to observe the outcomes.

function limit(string, maxLength) {
  let visit = function(node) {
    if (count < maxLength) {
      if (node.nodeType === Node.TEXT_NODE) {
        let left = maxLength - count;
        let length = node.nodeValue.length;

        if (length > left) {
          node.nodeValue = node.nodeValue.substring(0, left) + '...';
          count += left;
        } else {
          count += length;
        }
      } else {   
        for (let childNode of Array.from(node.childNodes)) {
          visit(childNode);
        }
      }
    } else {
      node.remove();
    }

    return node;
  };
  let dom = new DOMParser().parseFromString(string, "text/html");
  let tree = dom.body;
  let count = 0;

  return visit(tree).innerHTML;
}

let string = 'Click <a href="http://stackoverflow.com">this absolutely <b>ah-mah-zing</b> link</a> to access Stackoverflow.';

document.getElementById('container').innerHTML = [20, 25, 30, 35, 40, 45, 50]
        .map(maxLength => limit(string, maxLength))
        .join('<br>');
<div id="container"></div>

Upsides

  • All relevant tags, even nested ones, are preserved perfectly
  • Precision is ensured as HTML tags and attributes do not influence character display limit

Downsides

  • Performance may not be optimal, although potential optimizations exist (e.g., skipping serialization back to HTML, sharing the DOMParser instance, etc.)

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

Tips for addressing lag problems in my Three.js game as time progresses

My game in Three.js doesn't start off with any lag, but after a few minutes, the performance begins to slow down on computers running it. I've tried reviewing my code and checking my arrays, adjusting values to troubleshoot, but so far, nothing s ...

Developing a 3D spherical material for WebGL rendering in Three.js

My current threejs example features particles being rendered onto a spherical object using the canvas with the program function. Here's a snippet of the code: var material = new THREE.ParticleCanvasMaterial( { color: 0xffffff, program: f ...

Prevent submission of angularjs form when image exceeds size limit

Here is a form with custom file upload functionality: <div class="form-group"> <input type="file" id="files" file-upload="myFile" ng-disabled="isBig" class="form-control" name="files" /> <output id="list"></output> </div> ...

Executing a Ruby function via AJAX

I am fairly new to working with ajax, and I find myself in need of using it for my Rails application. Here is the function in my controller: def check_code input = params[:input] code = params[:code] if input == code return true else retur ...

Convert Number to Decimal Format with Additional Four Decimal Places

Implementing Angularjs version 1.xx var processedInput = text.replace(/[^0-9.]/g, '') .replace(/\B(?=(\d{3})+(?!\d))/g, ","); if(processedInput!="") processedInput="$"+processedInput; Input = 123456789, Desired Ou ...

Vuejs v-for nested loops

After spending countless hours researching, I am determined to solve this problem. My objective is to create a questionnaire similar to a Google Form, with question groups, questions, and answers. The structure of my data looks like this: question_group: ...

Utilizing correct Django CSRF validation when making a fetch post request

I've been experimenting with JavaScript's fetch library to perform a form submission on my Django application. Despite my efforts, I keep running into CSRF validation issues. The Ajax documentation suggests specifying a header, which I have atte ...

Generate an array of HTML files from external sources and randomize their placement within multiple div containers

I am currently working on a website that features a grid made up of divs (4x4) which need to have a set of texts shuffled into them every time the page is reloaded. You can see what it looks like here. Within my index.htm file, I have the following struct ...

A guide on how to apply filtering to an array in Vue using another array

Currently, I have two arrays of objects: one is named submodules and it contains a children array within it. My goal is to filter these children arrays based on another array called accessed. new Vue({ data: { submodules: [ { type: ...

The standalone page loads smoothly, but it gets stuck when it is placed in an iframe

When I try to load this standalone page through an iframe using .load() within another page, it seems to hang. However, typing the address directly into the browser works fine. On this page , I have implemented an iframe to display the aforementioned pag ...

Utilize HTTPS and HTTP with Express framework in node.js

Currently, I am utilizing the express (3.0) framework on node.js to handle routing in my application. While most of the application makes use of the http protocol, there is a specific route that I intend to serve exclusively via https. This particular par ...

I am struggling with grasping the concept of the event system

I'm encountering an issue with the following code snippet: <template> <div class="chart" v-bind:style="chartStyleObject" v-on:mousedown.left="initHandleMousedown($event)" v-on:mouseup.left="initHandleMouseu ...

Trigger the Modal once the navigation step is completed

When navigating to a new page, I need to wait for the navigation process to complete in order for the modal template to be properly displayed on the destination page. public onOpenModal(item) { this.router.navigate([item.link]).then(() => { this. ...

Make sure to update the package.json file at multiple locations following the execution of the "npm i" command

My goal is to automatically detect any newly installed packages based on my package.json file. This way, whenever I run "npm i", the new package will be added not only to the usual "dependencies" section but also to a custom section called "extDependenci ...

What is the process for styling the <HTML> element effectively?

Query: How can I implement this style using JavaScript? jQuery would be appreciated as well :) Note: This style should be applied to the <HTML> element, not the document.body element. Otherwise, it will not work correctly. <style type="t ...

Incorporating ZeroClipboard or ZClip (button for copying to clipboard) using JQuery's Ajax functionality

Seeking to implement a 'copy to clipboard' feature triggered by clicking. However, I am facing a challenge as this functionality needs to be integrated with other content loaded using Ajax. Many plugins that achieve the same use Flash to bypass ...

accordions that are supposed to adapt to different screen sizes are

My custom responsive accordions are not functioning as expected. The requirement is to display headings and content for desktop view, but switch to accordions on smaller devices. I have managed to do this, however, when resizing the window, the functionali ...

Error in Redux app: Attempting to access the 'filter' property of an undefined value

I am currently encountering an issue with my reducer: https://i.stack.imgur.com/7xiHJ.jpg Regarding the props actual, this represents the time of airplane departure or arrival, and it is a property within my API. The API structure looks like this: {"body ...

Facing issues with debugging JavaScript using WebStorm lately

Previously, I had no issues debugging JavaScript from WebStorm with the help of the JetBrains Chrome extension. It would effortlessly open a new tab in Chrome and launch my site without any trouble. However, after rebooting my computer due to a Windows up ...

Continue running web AJAX request in Android browser while it is minimized

I need help with my AJAX call var tid = setInterval(mycode, 2000); function mycode() { $.ajax({ url:'/ajx.php', type: "GET", success: function (data) { }, ...