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?

Alan2
la source
3
jsfiddle.net/tUyyx
Ufuk Hacıoğulları

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)

EpokK
la source
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 ? '...' : ''}}
Govan
la source
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
svelte
la source
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;
   }
Sushrut
la source
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 ? '' : '...'}}
crc442
la source
Je supprimerais l'espace entre les deux sorties pour éviter la rupture de ligne
Ignacio Vazquez
21
< div >{{modal.title | limitTo:20}}...< / div>
Thiago Araújo
la source
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

Anam
la source
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>
mnishiguchi
la source
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>

Aleksandr Havrylov
la source
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

maudulus
la source
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...");
    });
});
SharkAlley
la source
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.

MAM
la source
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;

        }


    }
Shushanth Pallegar
la source
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

vhamon
la source
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',[])
Mohideen bin Mohammed
la source
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;
    }
Kurkula
la source
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}}
Harish Reddy Pothula
la source
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 }} 
Mel Michael
la source
1
<div>{{modal.title | slice: 0: 20}}</div>
Vikas
la source
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: ')';
}
Dimitris
la source
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>
Amirul
la source
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
}
Helzgate
la source
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
Geoff
la source
0

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

GK
la source
0

J'utilise un bel ensemble de bibliothèque de filtres utiles "Angular-filter" et l'un d'eux appelé "tronquer" est également utile.

https://github.com/a8m/angular-filter#truncate

l'utilisation est:

text | truncate: [length]: [suffix]: [preserve-boolean]
Lukas Jelinek
la source