Limitez la longueur d'une chaîne avec AngularJS


225

J'ai ce qui suit:

<div>{{modal.title}}</div>

Existe-t-il un moyen de limiter la longueur de la chaîne à 20 caractères?

Et une question encore meilleure serait: existe-t-il un moyen de changer la chaîne à tronquer et de l'afficher ...à la fin si c'est plus de 20 caractères?


Réponses:


344

Modifier La dernière version du filtre d'AngularJS offres .limitTo

Vous avez besoin d'un filtre personnalisé comme celui-ci:

angular.module('ng').filter('cut', function () {
        return function (value, wordwise, max, tail) {
            if (!value) return '';

            max = parseInt(max, 10);
            if (!max) return value;
            if (value.length <= max) return value;

            value = value.substr(0, max);
            if (wordwise) {
                var lastspace = value.lastIndexOf(' ');
                if (lastspace !== -1) {
                  //Also remove . and , so its gives a cleaner result.
                  if (value.charAt(lastspace-1) === '.' || value.charAt(lastspace-1) === ',') {
                    lastspace = lastspace - 1;
                  }
                  value = value.substr(0, lastspace);
                }
            }

            return value + (tail || ' …');
        };
    });

Usage:

{{some_text | cut:true:100:' ...'}}

Options:

  • wordwise (boolean) - si vrai, couper uniquement par les limites des mots,
  • max (entier) - longueur maximale du texte, coupé à ce nombre de caractères,
  • tail (string, default: '…') - ajoutez cette chaîne à la chaîne d'entrée si la chaîne a été coupée.

Une autre solution : http://ngmodules.org/modules/angularjs-truncate (par @Ehvince)


2
Il y a un équivalent aux modules angulaires: ngmodules.org/modules/angularjs-truncate
Ehvince

angularjs-truncate n'est pas une solution, mais votre solution SI. Je vous remercie! Faites-en un module!
Anton Bessonov

@epokk Il existe un moyen de permettre à l'utilisateur, après avoir cliqué sur les trois points, d'afficher le texte non coupé complet? Comme un "montrer plus"? Merci!
Thales P

cela fonctionne bien lorsque nous l'utilisons comme ceci {{post.post_content | cut: true: 100: '...'}} Mais échoue lorsque j'utilise comme ceci <span ng-bind-html = "trustedHtml (post.post_content | cut: true: 100: '...')"> < / span> Parce que je suis obligé de l'utiliser avec du html de confiance dans mon cas
S Vinesh

La limite au niveau du mot est une fonctionnalité intéressante qui ne semble pas exister dans le "limitTo" par défaut
pdizz

496

Voici le correctif simple d'une ligne sans CSS.

{{ myString | limitTo: 20 }}{{myString.length > 20 ? '...' : ''}}

79
Simple et élégant. Au lieu de cela, '...'vous pouvez également utiliser l'entité HTML pour les points de suspension:'&hellip;'
Tom Harrison

probablement la solution la plus indolore. Gardez toujours à l'esprit que les filtres sont relativement lourds et que cela pourrait avoir des problèmes de performances sur une énorme liste de répétitions ng! :)
Cowwando

1
impressionnant! existe-t-il un moyen de couper après un certain nombre de lignes, plutôt qu'après un certain nombre de caractères?
axd

@axd Vous devez essayer cela en CSS ou écrire une directive pour y parvenir.
Govan

1
C'est la meilleure réponse. Le résultat de performance doit être négligeable avec un nombre raisonnable de ng-répétitions. Si vous ramenez des centaines de répétitions ng avec du contenu qui doit être tronqué, vous devrez peut-être revenir à la planche à dessin. Bonne réponse, @Govan
erier

59

Je sais que c'est tard, mais dans la dernière version d'angularjs (j'utilise 1.2.16), le filtre limitTo prend en charge les chaînes ainsi que les tableaux afin que vous puissiez limiter la longueur de la chaîne comme ceci:

{{ "My String Is Too Long" | limitTo: 9 }}

qui produira:

My String

9
Cette solution manque le "...". Le résultat devrait être: "My String ..."
Snæbjørn

Je ne vois pas les points de suspension ici: plnkr.co/edit/HyAejS2DY781bqcT0RgV?p=preview . Peux-tu élaborer?
slim

2
Ce que @ Snæbjørn dit, c'est que la personne qui a posé la question a préféré une solution qui insère "..." à la fin de la chaîne tronquée. La réponse de Govan fait cela.
Nahn

@Nahn merci de l'avoir signalé. J'aurais probablement dû faire un commentaire sur la réponse d'EpokK au lieu d'une autre réponse.
slim

52

Vous pouvez simplement ajouter une classe css à la div, et ajouter une info-bulle via angularjs pour que le texte découpé soit visible à la souris.

<div class="trim-info" tooltip="{{modal.title}}">{{modal.title}}</div>

   .trim-info {
      max-width: 50px;
      display: inline-block;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;  
      line-height: 15px;
      position: relative;
   }

4
débordement de texte: points de suspension, sympa.
Chris Russo

4
cette technique, bien qu'impressionnante, empêche le texte de s'habiller
Larry

Ceci est la bonne réponse. Ma règle générale est: "ne faites pas en JavaScript ce qui peut être fait en CSS".
aidan

4
Cela ne fonctionne que pour le texte avec une ligne par paragraphe. Voir pour multiline css-tricks.com/line-clampin (tous les navigateurs ne le prennent pas en charge).
Robert

Cela fonctionne également si vous essayez de limiter la longueur d'un tableau ng-repeat.
chakeda

27

J'ai eu un problème similaire, voici ce que j'ai fait:

{{ longString | limitTo: 20 }} {{longString.length < 20 ? '' : '...'}}

Je supprimerais l'espace entre les deux sorties pour éviter la rupture de ligne
Ignacio Vazquez

21
< div >{{modal.title | limitTo:20}}...< / div>

Approche la plus simple, mais fonctionnelle. Mais cela suppose que chaque titre aurait plus de 20 caractères et cela, dans certains cas, peut être inattendu.
Henrique M.

18

Solution plus élégante:

HTML:

<html ng-app="phoneCat">
  <body>
    {{ "AngularJS string limit example" | strLimit: 20 }}
  </body>
</html>

Code angulaire:

 var phoneCat = angular.module('phoneCat', []);

 phoneCat.filter('strLimit', ['$filter', function($filter) {
   return function(input, limit) {
      if (! input) return;
      if (input.length <= limit) {
          return input;
      }

      return $filter('limitTo')(input, limit) + '...';
   };
}]);

Démo:

http://code-chunk.com/chunks/547bfb3f15aa1/str-limit-implementation-for-angularjs


Puis-je suggérer d'ajouter un retour au cas où la inputvaleur est dynamique? à- dire le if (!input) {return;}cas contraire , il y aura des erreurs de console JS
mcranston18

1
@ mcranston18 ajouté. Je vous remercie.
Anam

15

Comme nous n'avons besoin de points de suspension que lorsque la longueur de la chaîne dépasse la limite, il semble plus approprié d'ajouter des points de suspension à l'aide ng-ifde la liaison.

{{ longString | limitTo: 20 }}<span ng-if="longString.length > 20">&hellip;</span>

7

Il y a une option

.text {
            max-width: 140px;
            white-space: nowrap;
            overflow: hidden;
            padding: 5px;
            text-overflow: ellipsis;(...)
        }
<div class="text">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Excepturi qui soluta labore! Facere nisi aperiam sequi dolores voluptatum delectus vel vero animi, commodi harum molestias deleniti, quasi nesciunt. Distinctio veniam minus ut vero rerum debitis placeat veritatis doloremque laborum optio, nemo quibusdam ad, sed cum quas maxime hic enim sint at quos cupiditate qui eius quam tempora. Ab sint in sunt consequuntur assumenda ratione voluptates dicta dolor aliquid at esse quaerat ea, veritatis reiciendis, labore repellendus rem optio debitis illum! Eos dignissimos, atque possimus, voluptatibus similique error. Perferendis error doloribus harum enim dolorem, suscipit unde vel, totam in quia mollitia.</div>


7

La solution la plus simple que j'ai trouvée pour simplement limiter la longueur de la chaîne était {{ modal.title | slice:0:20 }}, puis emprunter à @Govan ci-dessus, vous pouvez utiliser {{ modal.title.length > 20 ? '...' : ''}}pour ajouter les points de suspension si la chaîne est supérieure à 20, le résultat final est donc simplement:

{{ modal.title | slice:0:20 }}{{ modal.title.length > 20 ? '...' : ''}}

https://angular.io/docs/ts/latest/api/common/index/SlicePipe-pipe.html


4

Voici un filtre personnalisé pour tronquer le texte. Il est inspiré de la solution d'EpokK mais modifié selon mes besoins et mes goûts.

angular.module('app').filter('truncate', function () {

    return function (content, maxCharacters) {

        if (content == null) return "";

        content = "" + content;

        content = content.trim();

        if (content.length <= maxCharacters) return content;

        content = content.substring(0, maxCharacters);

        var lastSpace = content.lastIndexOf(" ");

        if (lastSpace > -1) content = content.substr(0, lastSpace);

        return content + '...';
    };
});

Et voici les tests unitaires pour que vous puissiez voir comment il doit se comporter:

describe('truncate filter', function () {

    var truncate,
        unfiltered = " one two three four ";

    beforeEach(function () {

        module('app');

        inject(function ($filter) {

            truncate = $filter('truncate');
        });
    });

    it('should be defined', function () {

        expect(truncate).to.be.ok;
    });

    it('should return an object', function () {

        expect(truncate(unfiltered, 0)).to.be.ok;
    });

    it('should remove leading and trailing whitespace', function () {

        expect(truncate(unfiltered, 100)).to.equal("one two three four");
    });

    it('should truncate to length and add an ellipsis', function () {

        expect(truncate(unfiltered, 3)).to.equal("one...");
    });

    it('should round to word boundaries', function () {

        expect(truncate(unfiltered, 10)).to.equal("one two...");
    });

    it('should split a word to avoid returning an empty string', function () {

        expect(truncate(unfiltered, 2)).to.equal("on...");
    });

    it('should tolerate non string inputs', function () {

        expect(truncate(434578932, 4)).to.equal("4345...");
    });

    it('should tolerate falsey inputs', function () {

        expect(truncate(0, 4)).to.equal("0");

        expect(truncate(false, 4)).to.equal("fals...");
    });
});

3

Vous pouvez limiter la longueur d'une chaîne ou d'un tableau à l'aide d'un filtre. Vérifiez celui-ci écrit par l'équipe AngularJS.


fournir également plus de détails
Parixit

3

En html, il est utilisé avec le filtre limitTo fourni par angular lui-même comme ci - dessous ,

    <p> {{limitTo:30 | keepDots }} </p>

filtre keepDots:

     App.filter('keepDots' , keepDots)

       function keepDots() {

        return function(input,scope) {
            if(!input) return;

             if(input.length > 20)
                return input+'...';
            else
                return input;

        }


    }

3

Si vous voulez quelque chose comme: InputString => StringPart1 ... StringPart2

HTML:

<html ng-app="myApp">
  <body>
    {{ "AngularJS string limit example" | strLimit: 10 : 20 }}
  </body>
</html>

Code angulaire:

 var myApp = angular.module('myApp', []);

 myApp.filter('strLimit', ['$filter', function($filter) {
   return function(input, beginlimit, endlimit) {
      if (! input) return;
      if (input.length <= beginlimit + endlimit) {
          return input;
      }

      return $filter('limitTo')(input, beginlimit) + '...' + $filter('limitTo')(input, -endlimit) ;
   };
}]);

Exemple avec les paramètres suivants:
beginLimit = 10
endLimit = 20

Avant : - /home/house/room/etc/ava_B0363852D549079E3720DF6680E17036.jar
Après : - /home/hous...3720DF6680E17036.jar


2
Use this in your html - {{value | limitTocustom:30 }}

and write this custom filter in your angular file,

app.filter('limitTocustom', function() {
    'use strict';
    return function(input, limit) {
        if (input) {
            if (limit > input.length) {
                return input.slice(0, limit);
            } else {
                return input.slice(0, limit) + '...';
            }
        }
    };
});

// if you initiate app name by variable app. eg: var app = angular.module('appname',[])

2

Cela peut ne pas provenir de la fin du script, mais vous pouvez utiliser le css ci-dessous et ajouter cette classe à la div. Cela tronquera le texte et affichera également le texte intégral au survol de la souris. Vous pouvez ajouter un texte plus et ajouter un hadler clic angulaire pour changer la classe de div sur cli

.ellipseContent {
    overflow: hidden;
    white-space: nowrap;
    -ms-text-overflow: ellipsis;
    text-overflow: ellipsis;
}

    .ellipseContent:hover {
        overflow: visible;
        white-space: normal;
    }

2

Si vous avez deux fixations {{item.name}}et{{item.directory}} .

Et souhaitez afficher les données sous forme de répertoire suivi du nom, en supposant «/ root» comme répertoire et «Machine» comme nom (/ root-machine).

{{[item.directory]+[isLast ? '': '/'] + [ item.name]  | limitTo:5}}

Y a-t-il une chance que vous ayez posté cette réponse sur la mauvaise question? Cela ne semble avoir rien à voir avec la limitation de la longueur d'une chaîne avec AngularJS.
BSMP

1

Vous pouvez utiliser ce module npm: https://github.com/sparkalow/angular-truncate

Injectez le filtre tronqué dans votre module d'application comme ceci:

var myApp = angular.module('myApp', ['truncate']); 

et appliquez le filtre dans votre application de cette façon:

{{ text | characters:20 }} 


0

J'ai créé cette directive qui le fait facilement, tronque la chaîne à une limite spécifiée et ajoute une bascule "afficher plus / moins". Vous pouvez le trouver sur GitHub: https://github.com/doukasd/AngularJS-Components

il peut être utilisé comme ceci:

<p data-dd-collapse-text="100">{{veryLongText}}</p>

Voici la directive:

// a directive to auto-collapse long text
app.directive('ddCollapseText', ['$compile', function($compile) {
return {
    restrict: 'A',
    replace: true,
    link: function(scope, element, attrs) {

        // start collapsed
        scope.collapsed = false;

        // create the function to toggle the collapse
        scope.toggle = function() {
            scope.collapsed = !scope.collapsed;
        };

        // get the value of the dd-collapse-text attribute
        attrs.$observe('ddCollapseText', function(maxLength) {
            // get the contents of the element
            var text = element.text();

            if (text.length > maxLength) {
                // split the text in two parts, the first always showing
                var firstPart = String(text).substring(0, maxLength);
                var secondPart = String(text).substring(maxLength, text.length);

                // create some new html elements to hold the separate info
                var firstSpan = $compile('<span>' + firstPart + '</span>')(scope);
                var secondSpan = $compile('<span ng-if="collapsed">' + secondPart + '</span>')(scope);
                var moreIndicatorSpan = $compile('<span ng-if="!collapsed">...</span>')(scope);
                var toggleButton = $compile('<span class="collapse-text-toggle" ng-click="toggle()">{{collapsed ? "less" : "more"}}</span>')(scope);

                // remove the current contents of the element
                // and add the new ones we created
                element.empty();
                element.append(firstSpan);
                element.append(secondSpan);
                element.append(moreIndicatorSpan);
                element.append(toggleButton);
            }
        });
    }
};
}]);

Et quelques CSS pour aller avec:

.collapse-text-toggle {
font-size: 0.9em;
color: #666666;
cursor: pointer;
}
.collapse-text-toggle:hover {
color: #222222;
}
.collapse-text-toggle:before {
content: '\00a0(';
}
.collapse-text-toggle:after {
content: ')';
}

0

Cette solution utilise uniquement ng balise sur HTML.

La solution est de limiter le long texte affiché avec le lien "afficher plus ..." à la fin de celui-ci. Si l'utilisateur clique sur le lien "afficher plus ...", il affichera le reste du texte et supprimera le lien "afficher plus ...".

HTML:

<div ng-init="limitText=160">
   <p>{{ veryLongText | limitTo: limitText }} 
       <a href="javascript:void(0)" 
           ng-hide="veryLongText.length < limitText" 
           ng-click="limitText = veryLongText.length + 1" > show more..
       </a>
   </p>
</div>

0

LA SOLUTION LA PLUS FACILE -> que j'ai trouvée est de laisser Material Design (1.0.0-rc4) faire le travail. Le md-input-containerfera le travail pour vous. Il concatène la chaîne et ajoute des elipses, plus il a l'avantage supplémentaire de vous permettre de cliquer dessus pour obtenir le texte complet, de sorte que c'est toute l'enchilada. Vous devrez peut-être définir la largeur du md-input-container.

HTML:

<md-input-container>
   <md-select id="concat-title" placeholder="{{mytext}}" ng-model="mytext" aria-label="label">
      <md-option ng-selected="mytext" >{{mytext}}
      </md-option>
   </md-select>
</md-input-container>

CS:

#concat-title .md-select-value .md-select-icon{
   display: none; //if you want to show chevron remove this
}
#concat-title .md-select-value{
   border-bottom: none; //if you want to show underline remove this
}

0

Limitez le nombre de mots avec un filtre angulaire personnalisé: voici comment j'ai utilisé un filtre angulaire pour limiter le nombre de mots affichés à l'aide d'un filtre personnalisé.

HTML:

<span>{{dataModelObject.TextValue | limitWordsTo: 38}} ......</span>

Code angulaire / Javascript

angular.module('app')
.filter('limitWordsTo', function () {
    return function (stringData, numberOfWords) {
        //Get array of words (determined by spaces between words)
        var arrayOfWords = stringData.split(" ");

        //Get loop limit
        var loopLimit = numberOfWords > arrayOfWords.length ? arrayOfWords.length : numberOfWords;

        //Create variables to hold limited word string and array iterator
        var limitedString = '', i;
        //Create limited string bounded by limit passed in
        for (i = 0; i < loopLimit; i++) {
            if (i === 0) {
                limitedString = arrayOfWords[i];
            } else {
                limitedString = limitedString + ' ' + arrayOfWords[i];
            }
        }
        return limitedString;
    }; 
}); //End filter

0

Cela fonctionne bien pour moi 'In span', ng-show = "MyCtrl.value. $ ViewValue.length> your_limit" ... en savoir plus. «durée de fin»


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.