67

I have some text like this:

<span>My text</span>

I want to display without tags:

My text

I also don't want to apply the tags, I want to strip them. What's an easy way to do that?

Angular html:

<div>{{myText | htmlToPlaintext}}</div>
Harry
  • 52,711
  • 71
  • 177
  • 261
  • You have tagged this under AngularJS, so I assume you want to do display the text using AngularJS. If so, is this text in a model? Which html tag are you using to display the contents of the model? – callmekatootie Jun 25 '13 at 05:44
  • @callmekatootie I created a filter based on the answer Abhishek gave. – Harry Jun 25 '13 at 05:56
  • 2
    I see that and his solution uses jQuery - You have tagged this under AngularJS and I have a feeling that you you can do it in AngularJS without using jQuery, if only you can give more information in your question - particularly where you wish to display the text in your view... – callmekatootie Jun 25 '13 at 06:16
  • @callmekatootie I added an example of what I'm doing in angular – Harry Jun 25 '13 at 07:05

8 Answers8

210

jQuery is about 40 times SLOWER, please do not use jQuery for that simple task.

function htmlToPlaintext(text) {
  return text ? String(text).replace(/<[^>]+>/gm, '') : '';
}

usage :

var plain_text = htmlToPlaintext( your_html );

With angular.js :

angular.module('myApp.filters', []).
  filter('htmlToPlaintext', function() {
    return function(text) {
      return  text ? String(text).replace(/<[^>]+>/gm, '') : '';
    };
  }
);

use :

<div>{{myText | htmlToPlaintext}}</div>  
Elan Hasson
  • 1,214
  • 1
  • 19
  • 29
Utopik
  • 3,783
  • 1
  • 21
  • 24
  • 7
    I actually prefer String(text).replace(/<[^>]+>/gm, ''). I've been using it for years without any issues. – blockloop Jan 27 '14 at 20:47
  • 14
    jQuery is 40 times slower, but you still get 8000 ops/s, so not using jQuery for that reason is premature optimization. – Blaise Apr 16 '14 at 10:31
  • @Blaise you are right, 8k ops/s is enough. But think of the whole picture. Is your app doing only that ? What about mobiles ? What about heavy applications ? Is there any browser compatibility issue involved ? What are the advantages of jQuery ? Is jQuery more readable ? Is jQuery easy to write ? Sometimes jQuery is good enough. But jQuery should not be used everywhere. Especially not here. – Utopik Apr 16 '14 at 17:06
  • 4
    I would never add a jQuery dependency just to convert html to text, but if my project already used jQuery I would choose the jQuery solution because I consider a custom-written regular expression less readable, less tested and less reliable. Does your regular expression protect against [all possible forms of XSS](https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet)? – Blaise Apr 16 '14 at 17:57
  • @Blaise, if you add the text into the DOM with jQuery, you don't have to protect against XSS into **this** function. jQuery does it when added to the DOM. BTW, I'm really not sure which one is more readable. – Utopik Apr 16 '14 at 18:48
  • 1
    using the DOM engine covers a lot more cases that this simple replace those not example: some codes here ’ “ ” – Bogdan Apr 10 '15 at 18:06
  • 4
    You should probably add a null-check in there, or it will output "null": `return text ? String(text).replace(/<[^>]+>/gm, '') : "";` – Björn Apr 29 '15 at 11:54
  • 1
    I'm wary of this solution. There's a number of circumstances where it will fail: 1. A less than sign '<' appearing in the text that's not a tag, i.e.

    One < Two

    . The string "< Two
    – Bri Bri Sep 15 '15 at 15:56
  • You could shorten the regexp with a nongreedy search `/<.+?>/gm,` which looks a bit more intuitive, readable and also saves you a few characters. – kernel Feb 29 '16 at 15:23
  • This does not work if the html text is following. `"

    Some Text.


    "`
    – Samarth Agarwal Mar 11 '16 at 03:23
  • @SamarthAgarwal what's wrong? it returns `Some Text.`, as I would expect it – Utopik Mar 11 '16 at 21:32
  • How to show the preview ,instead of showing the plain text(it is working). but i need to show the preview like stack overflow shows while posting question or answer including images also – codelearner Jun 07 '16 at 08:13
  • This will not work if there are close angle brackets in attributes or comments. For example, `image

    HelloWorld

    `
    – David Conrad Nov 29 '22 at 19:35
21

from https://docs.angularjs.org/api/ng/function/angular.element

angular.element

wraps a raw DOM element or HTML string as a jQuery element (If jQuery is not available, angular.element delegates to Angular's built-in subset of jQuery, called "jQuery lite" or "jqLite.")

So you simply could do:

angular.module('myApp.filters', []).
  filter('htmlToPlaintext', function() {
    return function(text) {
      return angular.element(text).text();
    }
  }
);

Usage:

<div>{{myText | htmlToPlaintext}}</div>
Dan Beaulieu
  • 19,406
  • 19
  • 101
  • 135
Davy R
  • 329
  • 2
  • 4
  • 2
    I would avoid this approach as well; might not take as long as full jQuery, but certainly much slower than accepted answer. – jake Jul 01 '14 at 19:22
  • 3
    I suggest wrapping your text in an element otherwise a plain old string like "hi" will return an empty string `angular.element('
    '+text+'
    ').text();`
    – Chris Jacob Jul 02 '14 at 06:18
  • if you're in the link function of a directive you can simply do element.text() 0.o – Jordan Dec 02 '14 at 18:38
  • 2
    I prefer this solution to using a regex, at least in cases where speed isn't critical. It's more correct and will actually convert the html to plain text, extraneously less than signs, special entities and all. – Bri Bri Sep 15 '15 at 15:58
  • How to show the preview ,instead of showing the plain text(it is working). but i need to show the preview like stack overflow shows while posting question or answer including images also – codelearner Jun 07 '16 at 08:13
  • If your html have inline style then accepted answer fails, this way works fine :) – kaxi1993 Dec 16 '16 at 11:31
  • Kudos to this, using regex is quick but there will be edge cases where it fails. This is a simpler and safer way when performance is not critical. Thanks! – Bruce May 25 '17 at 01:10
  • This will fail if `text` is not already wrapped in some HTML tag. So to be robust it should be more like: `return angular.element('
    ' + text + '
    ')`
    – Episodex Jan 11 '18 at 12:32
4
var app = angular.module('myapp', []);

app.filter('htmlToPlaintext', function()
{
    return function(text)
    {
        return  text ? String(text).replace(/<[^>]+>/gm, '') : '';
    };
});

<p>{{DetailblogList.description | htmlToPlaintext}}</p>
ajshort
  • 3,684
  • 5
  • 29
  • 43
  • 1
    add some formating an some insights to the code, that helps to generate better answers. – winner_joiner Mar 09 '16 at 07:13
  • 2
    Please add some explanation. Your answer is currently flagged "low quality" and might eventually be removed. – Johannes Jander Mar 09 '16 at 09:25
  • There's a difference between a low-quality answer that should be voted down and a non-answer that should be deleted. Please see [You're doing it wrong: A plea for sanity in the Low Quality Posts queue](http://meta.stackoverflow.com/questions/287563/youre-doing-it-wrong-a-plea-for-sanity-in-the-low-quality-posts-queue). – twernt Mar 10 '16 at 14:55
  • How to show the preview ,instead of showing the plain text(it is working). but i need to show the preview like stack overflow shows while posting question or answer including images also – codelearner Jun 07 '16 at 08:13
3

You want to use the built-in browser HTML strip for that instead of applying yourself a regexp. It is more secure since the ever green browser does the work for you.

angular.module('myApp.filters', []).
  filter('htmlToPlaintext', function() {
    return function(text) {
      return stripHtml(text);
    };
  }
);

var stripHtml = (function () {
  var tmpEl = $document[0].createElement("DIV");
  function strip(html) {
    if (!html) {
      return "";
    }
    tmpEl.innerHTML = html;
    return tmpEl.textContent || tmpEl.innerText || "";
  }
  return strip;
}());

The reason for wrapping it in an self-executing function is for reusing the element creation.

Olivier C
  • 1,151
  • 10
  • 11
  • How to show the preview ,instead of showing the plain text(it is working). but i need to show the preview like stack overflow shows while posting question or answer including images also – codelearner Jun 07 '16 at 08:14
  • changed $document[0] to document and it worked for me! Thank you – Allen Hamilton Oct 05 '16 at 23:26
3

<div ng-bind-html="myText"></div> No need to put into html {{}} interpolation tags like you did {{myText}}.

and don't forget to use ngSanitize in module like e.g. var app = angular.module("myApp", ['ngSanitize']);

and add its cdn dependency in index.html page https://cdnjs.com/libraries/angular-sanitize

Prasanna
  • 1,752
  • 1
  • 15
  • 27
0

You can use ng-bind-html, don't forget to inject $sanitize service into your module Hope it helps

Hung Vu
  • 5,624
  • 2
  • 30
  • 27
-3

Use ng-bind-html this is only proper and simplest way

  • Welcome to Stack Overflow. Please add more details for clarification. Once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post;](http://stackoverflow.com/help/privileges/comment) instead, [provide answers that don't require clarification from the OP](http://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). – mmushtaq Jan 03 '17 at 10:39
-7

Use this function like

 String.prototype.text=function(){
   return this ? String(this).replace(/<[^>]+>/gm, '') : '';
 }

  "<span>My text</span>".text()
  output:
  My text

Fiddle

pixelbyaj
  • 1,178
  • 1
  • 9
  • 22
  • 8
    This is a jQuery-based solution. The question was about angularjs. – RevNoah Jun 02 '14 at 21:21
  • Rev The mark answer is javascript and if I did it using jquery what make it difference – pixelbyaj May 29 '15 at 10:08
  • 1
    Your solution is not compatible with OP's requirements. he already built his app on angularjs. jquery is a different framework. – Ibrahim Lawal Jun 21 '15 at 10:19
  • 1
    +1 and I don't see here any jQuery... wtf? Another problem is @Abjo's method extends build in String prototype. That some developers choose to be angry about. – Marecky Aug 23 '17 at 10:50