Angular: Truncating text based on element width - A guide

I am working on displaying a String text and determining how many words to hide based on the screen width.

Here is my current approach:

 app.filter('words', function () {
        return function (input, words) {
            if (isNaN(words)) return input;
            if (words <= 0) return '';
            if (input) {
                var inputWords = input.split(/\s+/);
                if (inputWords.length > words) {

                    var wordCount = inputWords.length - words;

                    input = inputWords.slice(0, words).join(' ') + ' + ' + wordCount;
                }
            }
            return input;
        };
    });

This filter currently works for a fixed count of words. For instance, if words is set to 5, only 5 words will be displayed while the rest are hidden.

However, I am looking for a way to make the number of words dynamic based on the width of the element. For example, if a <div> has a width of 200px, I want to show 12 words, adjusting the count based on the width.

I believe a directive that can take the element's width and calculate the appropriate number of words is needed.

Check out this Demo:

DEMO

Thank you in advance for your assistance.

Answer №1

Check out this custom directive I created:

app.directive('characterLimit', function($compile){
    return{
        restrict: 'E',
        replace: true,
        scope: {
            maxLength: '=',
            textContent: '='
        },
        template: '<div style ="border-style: solid; max-width:{{maxLength}}px"><span>{{textContent}}</span></div>',        
        link: function(scope, element, attrs){            
            scope.$watch('maxLength', function(value){          
                if(isNaN(scope.maxLength) || scope.maxLength < 0)
                    return;
                var charCount = Math.floor(scope.maxLength / 15); 
                var inputText = scope.textContent.split('');
                var excessChars = inputText.length - charCount;
                console.log('Element max width: ' + scope.maxLength);
                console.log("Number of characters: " + inputText.length);
                console.log("Characters to show: " + charCount);

                element[0].innerHTML = inputText.slice(0, charCount).join('') + ' + ' + excessChars;          
            });
        }
    };
});

The functionality is contained within the link function and heavily relies on your existing code. To use this directive, simply do the following:

<character-limit max-length="<maxWidth>" text-content="<textContent>"></character-limit>

In this case, <maxWidth> defines the maximum width for the div, while <textContent> represents the text you want to display. In my implementation, I used a basic calculation of maxLength/15 to determine the character limit. You may need to devise a more intricate approach based on your requirements.

Feel free to check out this Fiddle showcasing the directive in action.

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 on utilizing ajax to load context without needing to refresh the entire page

As a beginner in AJAX, I have some understanding of it. However, I am facing an issue on how to refresh the page when a new order (order_id, order_date, and order_time) is placed. I came across some code on YouTube that I tried implementing, but I'm n ...

Reordering elements in ng-repeat using Angular's orderBy filter for ascending sorting

My JSON data looks like this: "db" : { "x" : { "0" : "A", "1" : "B", "2" : "C", "3" : "D", "4" : "E", "5" : "F", "6" : "G", "7" : "H", "8" : "I", "9" : "J", "10" : ...

Collection of components displayed in a row - Bootstrap 4

In order to meet the requirement, the label must be positioned above the input element, and the group consisting of each label and input element should be displayed inline with one another. I have managed to achieve this using the following code snippet, ...

What is the best method for displaying an HTML string within an HTML file in Angular 5?

I have declared an array in my TypeScript file like this: import {Component, OnInit} from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'app-foo', template: ...

The Context API leaves me feeling lost and confused

I am currently utilizing Auth0 for user sign up. My goal is to extract the user id listed under sub:value, and then add it to my database to associate it with a user's post. To achieve this, I am attempting to utilize a Context API to retrieve the use ...

AWS: Grant access to designated clients for users

My AWS Cognito setup includes: AWS Cognito User Pool: UserPool_1 The User Pool contains 3 users: Mike, Sarah, John I have configured 3 App Clients under this user pool: WebClient_1 WebClient_2 WebClient_3 I need Mike to be able to access: WebClient_ ...

The MobX computed function is triggered before the item is fully added to the array

I am currently using React in combination with MobX. In my store, I have an observable array called 'conversations' and I want to create a sorted version of this array as a computed property. However, when I add a new conversation, the sortedConv ...

"Struggling to make the 'overflow: hidden' property work for an absolutely positioned

I'm struggling to conceal an absolutely positioned image within a CSS grid layout. Below is the code snippet: HTML: <div class="relative-parent"> <div v-for="item in 12" class="hiding-parent"> <div c ...

Having trouble showing an image with jQuery after it has been uploaded

Currently, I have a URL that shows an image upon loading. However, I want to provide the option for users to replace this image using a form input. My goal is to display the uploaded image as soon as it's selected so users can evaluate it. I'm a ...

chart for visualizing two rows with matching IDs and dates

I have been attempting to accomplish the following two scenarios: 1) When both ID and dates are the same in the chart, but the descriptions differ, I want to display them on separate lines. 2) If there is not enough room to show the row label, I would li ...

Creating a unique navigation route in React

My application has a consistent layout for all routes except one, which will be completely different from the rest. The entire application will include a menu, body, footer, etc. However, the one-off route should be standalone without these elements. How ...

Retrieve the values of private variables within a defined function

While experimenting with typescript, I have encountered an issue that I can't seem to resolve. My project involves using Angular, so I will present my problem within that context. Here is a snippet of my code: class PersonCtrl{ private $scope: I ...

Validating Forms in AngularJS: Ensuring At Least One Input Field is Not Empty

Consider the following basic HTML form: <form name="myForm" action="#sent" method="post" ng-app> <input name="userPreference1" type="text" ng-model="shipment.userPreference" /> <input name="userPreference2" type="text" ng-model="shipm ...

Guide on displaying applicant name in the show route of your node.js/mongoDB application

Currently working on a website where applications are being accepted. In the admin panel, I want to display a list of all applicants and allow users to click on a name to view more information. However, I'm facing an issue where the same applicant is ...

Is it beneficial to incorporate keys into an express instance for improved functionality?

If I want to pass information from my index.js file to multiple endpoints across different routes, is it sufficient to attach a custom key to the express instance (app)? For instance, if I am using socket.io and want multiple endpoints to emit from the i ...

How should props be properly passed to NavItem components?

Although my code is functional, it produces an error. I am seeking advice on how to prevent this error from occurring in the future. I am eager to improve my coding skills and write accurate code. This is a snippet of my current code: export const Aut ...

Tips on increasing the height of an element that is overflowing

When populating my timeline component with dynamically mapped data from an array, I encountered an issue where if I added more data causing the maximum height to be reached, the overflow-y element didn't display all content. Despite trying various sol ...

The vast expanse of the cosmos, replacing the

When attempting to simulate pressing the ENTER key in my code, I am getting the same result as if I pressed SPACE instead. I'm not sure why this is happening. field.clear().click().sendKeys("Hello"); browser.actions().sendKeys(protractor.Key.ENTER).p ...

Undefined value in Axios promise pending status in React

I'm currently working on developing a weather application using React. To enable a dropdown feature listing available cities and to fetch data from an API, I am incorporating react-autosuggest for the dropdown functionality and Axios for making API ca ...

Leverage Webpack's File-Loader to Import Images

I have implemented Webpack in my React application. I have added 'File-loader' & 'Url-loader' to my webpack configuration. But I am uncertain about how to connect images to my components. I'm storing the image source ('s ...