9

This one has me stumped. I want to remove the "+" from a label element. Here's the HTML:

 <label class="option" for="edit-attributes-21-33">
 <input type="radio" id="edit-attributes-21-33" name="attributes[21]" 
 value="33" checked="checked" class="form-radio"> 4 oz, +$15.00</label>

I started with this

$(".option").each(function(index, value) {

$(this).text( $(this).text().replace("+", ""));

})

This removes the "+" but also strips out the input element. So then I tried:

$(".option").each(function(index, value) {

var oldString = $(this).html();
var newString = oldString.replace("+", "");
console.log(oldString, newString);
$(this).text(newString);

})

This makes a string of the correct html mark-up, but it's a string and is passed back to the DOM that way. I've seen another post with the same problem, but no solution.

icicleking
  • 1,029
  • 14
  • 38
  • Related but not quite duplicate: http://stackoverflow.com/questions/4106809/how-can-i-change-an-elements-text-without-changing-its-child-elements – James Montagne Apr 15 '15 at 19:59
  • I am not sure what you mean by the input element is stripped out? Give an example of what it is originally, what it becomes after the current code, and what you would like it to do. EX: Original: `Abc + 123 + 456` should be `Abc 123 + 456` but this code returns `Abc 123 456` – Addo Solutions May 14 '15 at 13:55

3 Answers3

6

You can achieve what you want using your code by using .html() instead of .text():

$(".option").each(function(index, value) {
    var oldString = $(this).html();
    var newString = oldString.replace("+", "");
    console.log(oldString, newString);
    $(this).html(newString);
});

Here's the JQuery .html() method ref: https://api.jquery.com/html/

Here's the Fiddle: https://jsfiddle.net/Darkseal/1c572Luw/

I also slightly modified your <input> end tag to make it XHTML compliant.

Darkseal
  • 9,205
  • 8
  • 78
  • 111
  • 2
    This looks pretty identical to the 2nd block of code from the question. What have you changed? – James Montagne Apr 15 '15 at 19:36
  • Why the downvote? This solution works perfectly. It's using `.html()` instead of `.text()`. – emerson.marini Apr 15 '15 at 19:39
  • He used `.text()` instead of `.html()`. I just fixed the code more than rewrite that so he can understand the difference and then shrink it in an one-liner like `$(".option").html($(".option").html().replace("+", ""))` or something like that. I really don't understand the downvote, my answer is correct. – Darkseal Apr 15 '15 at 19:39
  • 1
    .replace("+", "") will only replace the first instance of "+" ; Add a global flag if you want to remove all instances of "+"; e.g. [.replace(/\+/g, ' ')](http://stackoverflow.com/questions/13574980/jquery-replace-all-instances-of-a-character-in-a-string) – joshvito Apr 15 '15 at 19:42
  • @joshvito Agreed. A regular expression should be used here instead, but then, the OP didn't mention multiple occurrences of the char to be replaced. – emerson.marini Apr 15 '15 at 19:44
  • 2
    It's helpful to include an explanation of what you have changed and why. Also, an input without the slash at the end is perfectly valid in html5. I believe only xhtml requires the slash. – James Montagne Apr 15 '15 at 19:45
  • 1
    I only answered the OP question. Anyway, you can use .replace(/\+/g, "") if you need to replace all occurrences. – Darkseal Apr 15 '15 at 19:45
  • 2
    I'm not quite sure what you did to make the input tag 'HTML5 compliant', it's a void element – Marc Apr 15 '15 at 19:45
  • I fixed the answer including a brief explanation of what I did and replaced HTML5 with XHTML. Thanks for the prompt suggestions, great community as always :) – Darkseal Apr 15 '15 at 19:49
  • One final (possible) issues with this approach is that it will "clear" the state of the input when re-entering it into the DOM. This may not be an issue if the code only runs on page load. However, if it runs later, consider if the input box was initially unchecked. If the user were to check the radio button and then this code ran, the radio button would return to an unchecked state. This is true for any element property (but not attributes). – James Montagne Apr 15 '15 at 19:53
  • @JamesMontagne I've posted a late answer taking this into consideration. – emerson.marini Apr 15 '15 at 20:16
4

What you're looking for is called a textNode. I gave your label an ID to make it easier, but the priciple remains the same for other selectors:

var node = document.getElementById("example").childNodes[2];
node.nodeValue = node.nodeValue.replace("+", "");

With a simple demo.
You should try to use plain JS as much as you can in favour in jQuery. Plain JS is often a lot faster than jQuery is.

After the comment, if you don't know the exact position of the textnode, check this.

Community
  • 1
  • 1
Martijn
  • 15,791
  • 4
  • 36
  • 68
  • 1
    What if he doesn't know exactly the position of the textNode? – jmartins Apr 15 '15 at 19:44
  • 1
    Great solution using just `Vanilla Javascript`. – emerson.marini Apr 15 '15 at 19:49
  • than you need to click the "exact position" link and figure out a way to find what you want ;) – Martijn Apr 15 '15 at 19:51
  • Manipulating the text nodes is definitely the cleanest approach. You would likely want to loop over them to find the correct one(s). I tried to find a good duplicate question with a thorough answer but couldn't find one, so I'll leave this question open. – James Montagne Apr 15 '15 at 19:56
  • Very cool, I did the other solution, but I'll give this a try when I have a chance. I do need to loop over all the elements, so I was already using jQuery .each, so I stayed in jQuery land. – icicleking Apr 15 '15 at 20:03
  • You should try to use plain JS as much as you can in favour in jQuery. Plain JS is often a lot faster than jQuery is. – Martijn Apr 15 '15 at 20:50
  • 1
    @Martijn Thanks for this, I had a similar problem today with excess text in strings(thanks ubercart!) and I Used your solution. Modified for the case at hand http://jsfiddle.net/3px7480v/3/ – icicleking Apr 16 '15 at 14:24
  • Here this would've been easier: `$('.date-display-single').each(function(){ $(this).html( $(this).html().replace('(All day','') )})` – Martijn Apr 16 '15 at 14:33
0

Late answer, just for the sake of showing a different approach using jQuery.

Here you would keep the input state, and wouldn't have the risk of replacing chars that you don't want to. Let's say you used + somewhere else, not just on the label text.

$(function () {
    $('label.option').each(function () {
        var label = $(this);
        var input = $('input.form-radio', this);
        var text = label.text();

        // Clean up the label contents.
        label.empty();        

        // Replace the char occurrences.
        text = text.replace(/\+/g, "");

        // Append both the input and the modified text.
        label.append(input).append(text);        
    });
});

Demo

emerson.marini
  • 9,331
  • 2
  • 29
  • 46