Limite la longitud de una cadena con AngularJS

225

Tengo lo siguiente:

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

¿Hay alguna manera de limitar la longitud de la cadena para decir 20 caracteres?

Y una pregunta aún mejor sería: ¿hay alguna manera de que pueda cambiar la cadena para que se trunca y mostrar ...al final si tiene más de 20 caracteres?

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

Respuestas:

344

Editar La última versión del filtro de AngularJSofertas .limitTo

Necesita un filtro personalizado como este:

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 || ' …');
        };
    });

Uso:

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

Opciones:

  • wordwise (boolean): si es verdadero, se corta solo por límites de palabras,
  • max (entero): longitud máxima del texto, cortada a este número de caracteres,
  • tail (string, default: '...'): agrega esta cadena a la cadena de entrada si se cortó la cadena.

Otra solución : http://ngmodules.org/modules/angularjs-truncate (por @Ehvince)

EpokK
fuente
2
Hay un equivalente en los módulos angulares: ngmodules.org/modules/angularjs-truncate
Ehvince
angularjs-truncate no es la solución, sino su solución IS. ¡Gracias! ¡Hazlo como módulo!
Anton Bessonov
@epokk ¿Hay una manera de permitir que el usuario, después de hacer clic en los tres puntos, muestre el texto completo sin cortar? ¿Como un "mostrar más"? ¡Gracias!
Thales P
esto funciona bien cuando lo usamos así {{post.post_content | cut: true: 100: '...'}} Pero falla cuando lo uso así <span ng-bind-html = "TrustedHtml (post.post_content | cut: true: 100: '...')"> < / span> Porque me veo obligado a usarlo con html de confianza en mi caso
S Vinesh
El límite de palabras es una buena característica que no parece existir en el "limitTo" predeterminado
pdizz
496

Aquí está la solución simple de una línea sin CSS.

{{ myString | limitTo: 20 }}{{myString.length > 20 ? '...' : ''}}
Govan
fuente
79
Simple y elegante En lugar de '...'usted también puede usar la entidad HTML para puntos suspensivos:'&hellip;'
Tom Harrison
Probablemente la solución más indolora. ¡Tenga en cuenta que los filtros son relativamente pesados ​​y esto podría tener problemas de rendimiento en la enorme lista de ng-repeat! :)
Cowwando
1
¡increíble! ¿Hay alguna forma de cortar después de varias líneas, en lugar de después de varios caracteres?
axd
@axd Debe probar eso en CSS o escribir una directiva para lograrlo.
Govan
1
Esta es la mejor respuesta. El impacto en el rendimiento debe ser insignificante con un número razonable de ng-repeat. Si está recuperando cientos de ng-repeat con contenido que necesita ser truncado, entonces es posible que deba volver al tablero de dibujo. Buena respuesta, @Govan
erier
59

Sé que esto es tarde, pero en la última versión de angularjs (estoy usando 1.2.16), el filtro limitTo admite cadenas y matrices para que pueda limitar la longitud de la cadena de esta manera:

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

que dará como resultado:

My String
Delgado
fuente
99
A esta solución le falta el "...". El resultado debería ser: "My String ..."
Snæbjørn
No veo los puntos suspensivos aquí: plnkr.co/edit/HyAejS2DY781bqcT0RgV?p=preview . ¿Puedes elaborar?
delgado
2
Lo que @ Snæbjørn dice es que la persona que hizo la pregunta prefirió una solución que inserte "..." al final de la cadena truncada. La respuesta de Govan hace eso.
Nahn
@Nahn gracias por señalar eso. Probablemente debería haber hecho un comentario a la respuesta de EpokK en lugar de otra respuesta.
delgado
52

Simplemente puede agregar una clase css al div y agregar información sobre herramientas a través de angularjs para que el texto recortado sea visible al pasar el mouse.

<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
fuente
44
desbordamiento de texto: puntos suspensivos, agradable.
Chris Russo
44
Esta técnica, aunque impresionante, evita que el texto se ajuste
Larry
Esta es la respuesta correcta. Mi regla general es: "no hagas en JavaScript lo que se puede hacer en CSS".
aidan
44
Esto solo funciona para texto con una línea por párrafo. Consulte css-tricks.com/line-clampin multilínea (no todos los navegadores lo admiten).
Robert
Esto también funciona si está intentando limitar la longitud de una matriz ng-repeat.
chakeda
27

Tuve un problema similar, esto es lo que hice:

{{ longString | limitTo: 20 }} {{longString.length < 20 ? '' : '...'}}
crc442
fuente
Quitaría el espacio en blanco entre ambas salidas para evitar el salto de línea
Ignacio Vázquez
21
< div >{{modal.title | limitTo:20}}...< / div>
Thiago Araújo
fuente
Enfoque más simple, pero funcional. Pero se supone que cada título tendría más de 20 caracteres y esto, en algunos casos, puede ser inesperado.
Henrique M.
18

Solución más elegante:

HTML:

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

Código angular:

 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) + '...';
   };
}]);

Manifestación:

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

Anam
fuente
¿Puedo sugerir agregar un retorno en caso de que el inputvalor sea dinámico? es decir, de lo if (!input) {return;}contrario habrá errores de la consola JS
mcranston18
1
@ mcranston18 agregado. Gracias.
Anam
15

Dado que necesitamos puntos suspensivos solo cuando la longitud de la cadena está por encima del límite, parece más apropiado agregar puntos suspensivos mediante el uso ng-ifque el enlace.

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

Hay una opcion

.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
fuente
4

Aquí hay un filtro personalizado para truncar texto. Está inspirado en la solución de EpokK pero modificado para mis necesidades y gustos.

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 + '...';
    };
});

Y aquí están las pruebas unitarias para que pueda ver cómo se supone que debe comportarse:

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...");
    });
});
TiburónAlley
fuente
3

Puede limitar la longitud de una cadena o una matriz utilizando un filtro. Mira este escrito por el equipo de AngularJS.

MAM
fuente
proporcione algunos detalles más también
Parixit
3

En html se usa junto con limitTo filter provisto por angular en sí como se muestra a continuación ,

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

filtro 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
fuente
3

Si desea algo como: InputString => StringPart1 ... StringPart2

HTML:

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

Código angular:

 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) ;
   };
}]);

Ejemplo con los siguientes parámetros:
beginLimit = 10
endLimit = 20

Antes : - /home/house/room/etc/ava_B0363852D549079E3720DF6680E17036.jar
Después : - /home/hous...3720DF6680E17036.jar

vhamon
fuente
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
fuente
2

Esto puede no ser del final del script, pero puede usar el siguiente CSS y agregar esta clase al div. Esto truncará el texto y también mostrará el texto completo al pasar el mouse. Puede agregar un texto más y agregar un controlador de clic angular para cambiar la clase de div en cli

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

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

Si tienes dos enlaces {{item.name}}y {{item.directory}}.

Y desea mostrar los datos como un directorio seguido del nombre, suponiendo '/ root' como el directorio y 'Machine' como el nombre (/ root-machine).

{{[item.directory]+[isLast ? '': '/'] + [ item.name]  | limitTo:5}}
Harish Reddy Pothula
fuente
¿Hay alguna posibilidad de que hayas publicado esta respuesta en la pregunta incorrecta? Esto no parece tener nada que ver con limitar la longitud de una cadena con AngularJS.
BSMP
1

Puede usar este módulo npm: https://github.com/sparkalow/angular-truncate

Inyecte el filtro truncado en el módulo de su aplicación de esta manera:

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

y aplique el filtro en su aplicación de esta manera:

{{ text | characters:20 }} 
Mel Michael
fuente
1
<div>{{modal.title | slice: 0: 20}}</div>
Vikas
fuente
0

Creé esta directiva que hace eso fácilmente, trunca la cadena a un límite especificado y agrega un conmutador "mostrar más / menos". Puede encontrarlo en GitHub: https://github.com/doukasd/AngularJS-Components

se puede usar así:

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

Aquí está la directiva:

// 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);
            }
        });
    }
};
}]);

Y algo de CSS para acompañarlo:

.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
fuente
0

Esta solución es puramente usando ng tag en HTML.

La solución es limitar el texto largo que se muestra con el enlace 'mostrar más ...' al final. Si el usuario hace clic en el enlace "Mostrar más ...", mostrará el resto del texto y eliminará el enlace "Mostrar más ...".

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
fuente
0

LA SOLUCIÓN MÁS FÁCIL -> que he encontrado es dejar que Material Design (1.0.0-rc4) haga el trabajo. El md-input-containerhará el trabajo por usted. Concatena la cadena y agrega elipses, además tiene la ventaja adicional de permitirle hacer clic para obtener el texto completo para que sea toda la enchilada. Es posible que deba establecer el ancho de 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
fuente
0

Limite la cantidad de palabras con un filtro angular personalizado: así es como utilicé un filtro angular para limitar la cantidad de palabras que se muestran usando un filtro personalizado.

HTML:

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

Código angular / 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
fuente
0

Funciona bien para mí 'In span', ng-show = "MyCtrl.value. $ ViewValue.length> your_limit" ... leer más. 'tramo final'

G K
fuente
0

Utilizo un buen conjunto de útiles bibliotecas de filtros "Angular-filter" y una de ellas llamada "truncar" también es útil.

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

el uso es:

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