Nate May
Nate May

Reputation: 4062

Change element text but leave inner span (or add span back) in jQuery

I have a bootstrap dropdown where the user selects "Past", "This", or "Next".

<div class="btn-group dropup three" role="group">
  <button type="button" class="btn btn-default dropdown-toggle" id="TPN" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
  This
    <span class="caret"></span>
  </button>
  <ul class="dropdown-menu fullwidth">
    <li><a onclick="setPast()">Past</a></li>
    <li><a onclick="setThis()">This</a></li>
    <li><a onclick="setNext()">Next</a></li>
  </ul> 
</div>

When an option is clicked it calls the appropriate function to change the text open the button. Example:

function setPast(){
   $('#TPN').text("Past");
}

However, this function strips away the span tag

<span class="caret"></span>

I can not figure out how to add this span. I have tried:

$('#TPN').append("<span class="caret"></span>");

and

$("TNP").text('new-text').append($('<span></span>').addClass('caret'));

How can I add this span, or better yet, what can I do to keep it from being removed in the first place?

Upvotes: 2

Views: 1470

Answers (4)

webketje
webketje

Reputation: 10976

I feel like I need to add: with plain JS, you can very, very easily do this without re-setting the span afterwards or modifying the HTML: elem.childNodes accesses text nodes [as well].

var elem = document.getElementById('TPN');
elem.childNodes[0].textContent = 'Past';

As for the dropdown menu, you could simplify:

function setText(e) {
  var target = e.target,
      txtNode = document.getElementById('TPN').childNodes[0];
  if (target.nodeName === 'A')
    txtNode.textContent = target.textContent;
}

var menu = document.getElementsByClassName('dropdown-menu')[0];
menu.addEventListener('click', setText, false);

And in HTML simply have:

<ul class="dropdown-menu fullwidth">
    <li><a>Past</a></li>
    <li><a>This</a></li>
    <li><a>Next</a></li>
</ul>

Upvotes: 0

jmar777
jmar777

Reputation: 39649

If you have very tight control over what the text is (specifically you know that text will never include other HTML), you can always just use regex and an .html() replacer function:

$('#TPN').html(function(i, oldHtml) {
    return oldHtml.replace(/^[^<]+/, 'new text');
});

Upvotes: 0

boszlo
boszlo

Reputation: 1286

Just put text in another span.

  <button type="button" class="btn btn-default dropdown-toggle" id="TPN" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
    <span class="text">This</span>
    <span class="caret"></span>
  </button>

Fiddle: https://jsfiddle.net/udzztobp/2/

Upvotes: 4

indubitablee
indubitablee

Reputation: 8206

alternatively to the answer above, if you want to add the caret back in, change:

$('#TPN').append("<span class="caret"></span>");

to this:

$('#TPN').append("<span class='caret'></span>");

Upvotes: 2

Related Questions