2

I have a textarea where user can edit some text and it accepts HTML. In the system, we can add a multimedia file to be added in the textarea. But when someone unlink the multimedia, i need to check if there is any of it in the textarea, remove it and put back on textarea.

So: I got a textarea like this

<textarea id="edNew-body" class="apply-jHtmlArea" style="width:550px;height:250px;"></textarea>`

When i add some multimedia, it comes like this for e.g.:

<audio src="whatever url" controls="controls" class="multimedia_666007" style="display: block; margin: 5px auto 10px; width: 320px; height: 35px; background-color: rgb(227, 227, 227);">-AUDIO-No support for HTML5</audio>`

So, when i remove the multimedia, i need to get all html inside the textarea and remove all elements with class=multimedia_NNNNN where NNNN will be a number.

I tried the following: Made a JSFiddle with below code

 dataId = '666007'; //not fixed, will come from somewhere from system
 var $currentHtml = $($("#edNew-body.apply-jHtmlArea").val());
 $currentHtml.find('.multimedia_'+dataId).remove(); //get all but ignore elements with this class
 $("#edNew-body.apply-jHtmlArea").val($currentHtml.html()); //put Html back without elements

I have tried the answer from those questions below but they only work on those issues. When i try adapt, i always end with [object Object] or just the first text 'something' without any html.

JQuery, remove element from string

String to jQuery object, how to remove elements

Remove element from html string in JQuery

Reading the answers i've learned that i need to use find because since it's user input, it can be or not nested in something (so i can't use remove('.classhere'))

Community
  • 1
  • 1
RaphaelDDL
  • 4,452
  • 2
  • 32
  • 56

2 Answers2

4

If you place the HTML in a container, then .find() will be able to search all the elements (since it never looks at elements at the top level).

Also, since .html() only gives you nested HTML content, putting it in a container will allow .html() to give you back the entire modified HTML content.

$('#rmv').click(function(e){
    e.preventDefault();
    var dataId = '666007'; 

      // Put the markup in a new container
    var $currentHtml = $('<div>').append($("#edNew-body.apply-jHtmlArea").val());

      // .find() will now be able to search through all the markup you added
    $currentHtml.find('.multimedia_'+dataId).remove();

      // .html() will now give you back all the markup (though modified)
    $("#edNew-body.apply-jHtmlArea").val($currentHtml.html()); 
});

http://jsfiddle.net/jR5bc/

  • So it was returning always 'something' because since had no container, it was using `.html()` on the first element it found? Since i never used find in a cached $var like that (only in normal DOM, like `$('#someid').find(..)` ), didn't knew about that. So if i tried `$('#someid').find('#someid')` it would never find anything, right? Thanks for the answer. – RaphaelDDL Jan 10 '12 at 14:01
  • 1
    @RaphaelDDL: Yeah, sort of. `.find()` only looks *inside* the topmost elements. So it was looking for the `'.multimedia_'+dataId` elements *inside* the `

    ` elements. Now you could have used `.filter()` instead of `.find()` to locate it, but that one *only* looks at the top level. So placing the content in a container lets you look at all the elements using `.find()`. And then the same with `.html()`, which only looks inside, so the container solved that too.

    –  Jan 10 '12 at 14:19
2

Check this fiddle: http://jsfiddle.net/ZDdWV/

Basically added a wrapper around your HTML text so as to make .find() work (it operates on nodes under the caller element)

techfoobar
  • 65,616
  • 14
  • 114
  • 135
  • 2
    Thank you for the answer as well. Since 'am not i am' and you answered on same time, i'll give +1 to both but set accepted to 'am not' since he got less points. – RaphaelDDL Jan 10 '12 at 14:02