Sisir
Sisir

Reputation: 2816

jQuery replaceWith() for HTML string

I am using filter() to select a list of elements then trying to replacing them by use of replaceWith(). The html is saved as string on a variable. It seem the replaceWith() is not working for me. When I log the variable content it shows the original string.

Is I know js objects are references. So, I was under the impression that replacing the selection will also replace element inside the string.

Here is the code

var content = '<div class="feature-box" contenteditable="false" data-sh-attr="%20title%3D%22jhk%22%20width%3D%224%22%20icon%3D%22thumbs-up%22" data-sh-content="kj"><div class="btn-panel"><a class="delete" href="#"><i class="fa fa-trash"> </i></a> <a class="edit" href="#"><i class="fa fa-pencil"> </i></a></div><div class="feature-icon-container"><i class="fa fa-thumbs-up main-icon"> </i></div><div class="feature-content"><h3>jhk</h3><div class="content">kj</div></div><div> </div></div><p>[block background_color="red" color="white"]Content of the block[/block]</p><p>This is an example page. It\'s different from a blog post because it will stay in one place and will show up in your site navigation (in most themes). Most people start with an About page that introduces them to potential site visitors. It might say something like this:</p><blockquote><p>Hi there! I\'m a bike messenger by day, aspiring actor by night, and this is my blog. I live in Los Angeles, have a great dog named Jack, and I like piña coladas. (And gettin\' caught in the rain.)</p></blockquote><p>...or something like this:</p><div class="feature-box" contenteditable="false" data-sh-attr="%20title%3D%22kk%22%20width%3D%224%22%20icon%3D%22thumbs-up%22" data-sh-content="kk"><div class="btn-panel"><a class="delete" href="#"><i class="fa fa-trash"> </i></a> <a class="edit" href="#"><i class="fa fa-pencil"> </i></a></div><div class="feature-icon-container"><i class="fa fa-thumbs-up main-icon"> </i></div><div class="feature-content"><h3>kk</h3><div class="content">kk</div></div><div> </div></div><blockquote><p>The XYZ Doohickey Company was founded in 1971, and has been providing quality doohickeys to the public ever since. Located in Gotham City, XYZ employs over 2,000 people and does all kinds of awesome things for the Gotham community.</p></blockquote><p>As a new WordPress user, you should go to <a href="http://localhost/l/factory/wp-admin/">your dashboard</a> to delete this page and create new pages for your content. Have fun!</p>';


jQuery(content).filter('.feature-box').each(function(){
    var $this = jQuery(this);   
    var attr = decodeURIComponent($this.data('sh-attr'));
    var content = decodeURIComponent($this.data('sh-content'));
    var shortcode = '[feature' + attr + ']' + content + '[/feature]';
    $this.replaceWith(shortcode);

});
console.log(content);

jsFiddle to play with

http://jsfiddle.net/du8d45tt/

Upvotes: 1

Views: 1528

Answers (3)

Ja͢ck
Ja͢ck

Reputation: 173542

Strings are immutable objects in JavaScript, so you need to overwrite it with another value:

content = jQuery('<div>', {html: content})
  .find('.feature-box')
    .replaceWith(function() {
      var $this = jQuery(this);   
      var attr = decodeURIComponent($this.data('sh-attr'));
      var content = decodeURIComponent($this.data('sh-content'));

      return '[feature' + attr + ']' + content + '[/feature]';
    })
    .end()
  .html();

This also uses .replaceWith(fn) syntax as a handy shortcut for .each() and using .replaceWith() inside.

Upvotes: 1

Ashley Medway
Ashley Medway

Reputation: 7301

You don't actually assign the updated html anywhere. $this.replaceWith(shortCode); updates $this not content.

You can use .html() to get the updated content and assign it back.
content = $this.replaceWith(shortcode).html();

Due to the asynchronous nature of the jQuery each method, it runs a callback, you should also have the console.log within the each function.

jQuery(content).filter('.feature-box').each(function(){
    var $this = jQuery(this);   
    var attr = decodeURIComponent($this.data('sh-attr'));
    var content = decodeURIComponent($this.data('sh-content'));
    var shortcode = '[feature' + attr + ']' + content + '[/feature]';
    content = $this.replaceWith(shortcode).html();
    console.log(content);
});

Upvotes: 1

Arun P Johny
Arun P Johny

Reputation: 388316

You are creating an dom structure and is modifying that dom structure, which won't modify the original string

To get the updated html, you need to get the updated content of the dom structure.

var $tmp = $('<div />', {
    html: content
})

$tmp.find('.feature-box').each(function () {
    var $this = jQuery(this);
    var attr = decodeURIComponent($this.data('sh-attr'));
    var content = decodeURIComponent($this.data('sh-content'));
    var shortcode = '[feature' + attr + ']' + content + '[/feature]';
    $this.replaceWith(shortcode);

});

var replaced = $tmp.html()
console.log(replaced);

Demo: Fiddle

Upvotes: 1

Related Questions