Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace content in elements without replacing HTML

Suppose I have the following HTML structure:

<test>
    <div>
        This is a test
        </div>
    <div>
        This is another test
        <button>
            Button test
        </button>
    </div>
</test>

Now I use the following jQuery code to replace, e.g., 'T':

$("test *").each(function(index, value) {
    $(this).html($(this).html().replace(new RegExp('t', "ig"), "<b>t</b>"));
});

However, this results in the following HTML structure (which is unexpected, see the <button> tag, which breaks my HTML):

<test>
    <div>
        <b>T</b>his is a <b>t</b>es<b>t</b>
        </div>
    <div>
        <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b>
        <bu<b>t</b><b>t</b>on>
            Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b>
            </bu<b>t</b><b>t</b>on>
        </div>
    </test>

What I want to achieve is:

<test>
    <div>
        <b>T</b>his is a <b>t</b>es<b>t</b>
        </div>
    <div>
        <b>T</b>his is ano<b>t</b>her <b>t</b>es<b>t</b>
        <button>
            Bu<b>t</b><b>t</b>on <b>t</b>es<b>t</b>
            </button>
        </div>
    </test>

Basically, I want to replace within the entire element but preserve the HTML tags and all the HTML attributes.

like image 247
TVA van Hesteren Avatar asked May 05 '17 16:05

TVA van Hesteren


Video Answer


1 Answers

With jQuery this could be achieved rather simply. Create a function that takes the element you wish to update the text of, the text you wish to replace and what you wish to replace it with. Then in the function you want to remove the child HTML and update any text left in the element with your replacement text. Then you can recursively run this same function for each of your child elements before appending them back into the parent.

function replaceTextInHtmlBlock($element, replaceText, replaceWith)
{
  var $children = $element.children().detach();
  //Now that there should only be text nodes left do your replacement
  $element.html($element.text().replace(replaceText, replaceWith));
  //Run this function for each child element
  $children.each(function(index, me){
    replaceTextInHtmlBlock($(me), replaceText, replaceWith);
  });
  $element.append($children);
}

$(document).ready(function(){
  $("#doReplace").click(function(){
    replaceTextInHtmlBlock($("#top"), $("#replace").val(), $("#with").val());
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="top">
  <div>
    This is a test
  </div>
  <div>
    This is another test
    <button>
            Button test
            </button>
  </div>
</div>
<br />
<br />
<div>
  <label>Replace</label>
  <input id="replace" value="t" />
  <label>with</label>
  <input id="with" value="<strong>t</strong>" />
  <button id="doReplace">Do Replace</button>
</div>
like image 69
John C Avatar answered Oct 16 '22 01:10

John C