Using pre-compiled values in an Angular directive within an ng-repeat loop

I'm currently working on a directive that should limit the text within an ng-repeat loop to 50 characters and add an ellipses if it exceeds this length. Here is how my ng-repeat is set up:

<li ng-repeat="result in topSuggestions.suggestions">
    <h4>{{result.title}</h4>
    <p suggestion-limiter>{{result.text}}</p>
</li>

This is the directive implementation:

app.directive("suggestionLimiter", [function () {
    return {
        restrict: "A",
        link: function (scope, elem, attrs) {
            console.log($(elem).text());
            var maxTextLength = 50;
            var ellipses = "...";
            var currentText = $(elem).text();

            if (currentText.length > maxTextLength) {
                 currentText = currentText.substr(0, maxTextLength - ellipses.length) + ellipses;
                 $(elem).text(currentText);
            }
        }
    }
}]);

When I log $(elem).text(), it displays as {{result.text}}. I've attempted using if (scope.$last) to ensure the completion of the ng-repeat loop but still facing the same issue. Any suggestions on what might be causing this?

Answer №1

However, I believe that a directive is not the most suitable solution for this particular task. It would be more appropriate to utilize a filter instead of a directive in order to modify the output of an expression. Consider the following approach:

filter('truncateWithEllipsis', function() {
  var ellipsis = '...';
  return function(text, limit) {
    text = typeof(text) !== 'undefined'? text: '';
    return text.length > limit?
      (text.substr(0, limit - ellipsis.length) + ellipsis):
      text;
  }
});

You can then proceed to use the filter within your ng-repeat as shown below:

 <ul>
   <li ng-repeat="item in list" ng-bind="item|truncateWithEllipsis:50"></li>
 </ul>

Feel free to explore this example that demonstrates its functionality.

Answer №2

One technique you can try is wrapping the function body with a `$timeout(function() { ... });`. By doing this, you can ensure that data binding has been completed.

app.directive("suggestionLimiter", ["$timeout", function ($timeout) {
    return {
        restrict: "A",
        link: function (scope, elem, attrs) {
            $timeout(function() {
                console.log($(elem).text());
                var maxTextLength = 50;
                var ellipses = "...";
                var currentText = $(elem).text();

                if (currentText.length > maxTextLength) {
                    currentText = currentText.substr(0, maxTextLength - ellipses.length) + ellipses;
                    $(elem).text(currentText);
                }
            });
         }
    }
}]);

Answer №3

One approach is to set your text as a data attribute of the directive and watch for any changes, eliminating the need for a timeout. Below is a rough code snippet that illustrates this concept. Adjusted the code to focus more on utilizing data attributes as the solution revolves around that.

Check out the live demo here

<body ng-controller="test">
<h1>Hello Plunker!</h1>

<div ng-repeat="item in data">
  <span data-limit="5" 
        data-overflow-text = ".."
        data-text="{{item}}" 
        suggestion-limiter></span>
</div>
<script>

  var app=angular.module("app",[]);

  app.directive("suggestionLimiter", function () {

    return {
        restrict: "A",
        link: function (scope, elem, attrs) {

            var maxTextLength = attrs.limit*1,
                overflowText = attrs.overflowText;

            attrs.$observe("text",function(v){
              if (v.length > maxTextLength) {
                 v = v.substr(0, maxTextLength - overflowText.length) + overflowText;
                 $(elem).text(v);
            }
            });


          }

        }
  });

app.controller("test", function($scope){

  $scope.data=[ "ssssssdsadsdddddd",
                "sssdsadsdddddikk",
                "adsssssssssdsadsdddod",
                "adsssssssssdsadsddioddd",
                "adsssssssssdsadsddkk'pdd",
                "8-adsdddddd",
                "6767ddd88809909"];
});

angular.bootstrap(document,["app"]);
</script>

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

Steps to create a dropdown select option using an AJAX call: When the data is fetched, it generates an array

How can I dynamically populate a dropdown with data from an array using jQuery and AJAX? <html> <script> $(document).ready(function() { $("#class_name").change(function(){ var class_id=$("#class_name").val(); ...

Using JavaScript and Regular Expressions for Performing Multiple Replacements

One issue that arises is that although the replacement functions as expected, all occurrences are replaced with the first find. (For example, see code below). The variable target represents the input field that contains the string to be highlighted, while ...

Display an input field in VueJS with a default value set

Dealing with a form containing various editable fields, I devised a solution. By incorporating a button, clicking it would conceal the label and button itself, while revealing a text box alongside a save button. The challenge lays in pre-filling the textbo ...

Check the status of the audio source URL using JavaScript

I am currently live streaming audio to my player using the Soundcloud API. <audio></aidio> <source src="soundcloud-track-url"></source> Within my code, I have added an onerror eventListener for both the <audio> and <sourc ...

Gatsby's own domain and absolute links: the perfect pair

My goal is to establish a direct link to files (such as images and downloads) in my static directory. During development, the link should be http://localhost/myimage.jpg, and once deployed, it needs to switch to https://www.example.com/myimage.jpg. Is the ...

New React Component Successfully Imported but Fails to Render

I've encountered issues with the code I'm currently working on. Dependencies: React, Redux, Eslinter, PropTypes, BreadCrumb Within a view page, I am importing components from other files. The current structure is as follows: import Component ...

Intersecting table columns with a different data table

My task is to create a table with a column that contains another table, where I want the colors of each alternating row to be different. Please refer to the image below (ignore the "CharacterAgain" column). Below is an example of AngularJS code for the ta ...

Moving information from two modules to the service (Angular 2)

Recently in my Angular2 project, I created two components (users.component and tasks.component) that need to pass data to a service for processing before sending it to the parent component. Code snippet from users.component.ts: Import { Component } fro ...

The property linerGradiant of r cannot be destructured because it is not defined

I encountered the error "Cannot destructure property linerGradiant of r as it is undefined" during runtime, making it difficult to debug. The issue seems to stem from the compiled JS file, which is hard to read. The function is defined as follows: functio ...

Tips for implementing angular js to automatically update a table after submitting a form:

Currently, I am working on developing an app using Python Flask and AngularJS. Within my index.html file, the code snippet below is present: <div ng=controller="QueryController as queryController"> <form> <input type="text" ng-model="query ...

Unable to input text by clicking using FabricJS combined with React and Jquery

I am currently working on a project using react and FabricJs. My goal is to add text to the fabricJS canvas by clicking on a button using jQuery. This is the code I have so far: import React, {Component} from 'react' import {fabric} from ' ...

Leveraging the power of ES6 syntax in Node scripts with Babel

My npm CLI tool utilizes ES6 syntax from BabelJS, specifically arrow functions. Within the entry point of my tool, I'm using the following require: require('babel-core/register'); var program = require('./modules/program.js'); I ...

Notification from HTML code within Django

In my Django project, I am trying to implement an alert. I am sending data from views.py to singup.html in order to display an alert based on certain conditions. However, initially the alert variable in HTML is not assigned a value. It is only after click ...

Having issues with reading files in PHP using AJAX? Explore alternative methods for downloading files seamlessly

I need to store a value in a txt file and allow the user to download it. Currently, the value is successfully written to the txt file, but the readfile function does not execute, preventing the download from starting. The PHP code is on the same page as ...

Different methods to avoid using $scope.$watch in a directive when dealing with an undefined variable

As I work on my angularjs application, I find myself utilizing directives for reusable UI elements across different pages. However, I encounter a challenge when a directive depends on a value from a promise. In such cases, I have to employ $scope.$watch al ...

How can I access the parent function within module.exports?

Hello, I am having issues with this code because I am unable to access checkIf in order to set its property LengthIs. When I log whether this is equal to module.exports, it returns false. Upon further inspection, I also checked what this was and it retur ...

Loading custom places in ArcGIS from a file or database

Hey there, I was wondering about loading custom places with Arcgis similar to Google maps loading from a .xml file. I noticed that Arcgis uses examples saved in .json format, but when I tried putting the example .json on my local server it wouldn't lo ...

What is the reason this JavaScript code functions properly within a <script> tag but not when placed in a separate .js

After researching various image sliders online, I came across this specific one. It worked perfectly fine when I included the JavaScript directly in a script tag within the HTML file. However, as soon as I tried to link it via a .js file, the slider stoppe ...

Is it possible to extract Django object values and convert them into JSON data for use in a JavaScript script on my HTML page

I've encountered a challenge in my Django project as I attempted to integrate a chart using Chart.js, only to realize that it requires the data input to be in JSON format. While I explored methods such as serialization and adjusting my views to conver ...

Randomly selecting JavaScript with different likelihoods or percentages

I am currently running a Node.js process with setInterval that occurs every 100ms. Within this process, I have specific actions that I want to execute at varying intervals such as 2% of the time for action X and 10% of the time for action Y. Currently, my ...