1

Can anyone help me this one? When I try to replace the currency symbol on this it moves the symbol inside the span tag which is causing problems with the rest of my code.

I've added my code to jsbin here: http://jsbin.com/usuraw/2

Thanks

<select id="inv_currency">
    <option value="£">£</option>
    <option value="€">€</option>
</select>

<span class="invE_balance currency">
£
<span>0.00</span>
</span>

JS:

$('#inv_currency').on('change', function() {

    var currency = $('.currency');

    if ($(this).val() == 'pound')   {
        currency.each(function( index ) {
            var text = '';
            text = $(this).text();
            text = text.replace("€", "£");
            $(this).text(text);
        });
    }
    else    {
        currency.each(function( index ) {
            var text = '';
            text = $(this).text();
            text = text.replace("£", "€");
            $(this).text(text);
        });
    }
});
adeneo
  • 312,895
  • 29
  • 395
  • 388
amof
  • 416
  • 7
  • 14

5 Answers5

2

Easiest way, without getting in to textNodes, is just break out the span for a second and replace the currency symbol, then replace the span. the reason I say this is because as soon as you call .text() you lose the child <span> within .currency. Basically:

<!-- original -->
<span class="currency">
  £ <span>0.00</span>
</span>

var currency = /*above .currency node */;
currency.text(currency.text().replace('£','€'));

<!-- resulting in -->
<span class="curency">€ 0.00</span>
<!-- note how you lose the child <span> -->

So, to avoid this you can play with moving the nodes around when you go to change the currency. this also gives you the ability to play around with symbol position and other things (maybe you want to add a format function that makes USD look like 100.00 and EURO look like 0,00). So, here's what I propose:

var currencySymbols = {
  pound: {
    symbol: '£',
    pos: 'left'
  },
  euro: {
    symbol: '€',
    pos: 'right'
  },
  usd: {
    symbol: '$',
    pos: 'left'
  }
};

//* currency
$('#inv_currency').on('change', function() {
  var symbol = currencySymbols[$(this).val()] || currencySymbols['euro'];
  $('.currency').each(function(i,e){
    var $span = $('span',this);
    $(this).empty().text(symbol.symbol);
    if(symbol.pos === 'left'){
      $span.appendTo(this);
    }else{
      $span.prependTo(this);
    }
  });
});

Refactored a bit (avoid using the replace), but also just essentially moves the span in and out of the node so you can place the symbols. I also make the symbol results objects so you can add additional information (like how the euro places the symbol to the right of the value using pos).

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
1
    if ($(this).val() == 'pound')   {

to

if ($(this).val() == '£')   {

demo here http://jsbin.com/usuraw/4/edit

Anton
  • 32,245
  • 5
  • 44
  • 54
1

Your selecting everything in the outer span and when you use .text() it is pulling the inner span as well. What you need to do is look at text nodes, see How do I select text nodes with jQuery?

Community
  • 1
  • 1
Robert Beuligmann
  • 1,434
  • 10
  • 13
1

And here's how you'd do it with textnodes:

$('#inv_currency').on('change', function () {
    var currency = $('.currency');
    if (this.value.trim() == '£') {
        currency.each(function (index) {
            var elem = $(this).contents().filter(function() {
                return this.nodeType === 3;
            });
            var text = elem.text();
            elem[0].nodeValue = text.replace("€", "£");
        });
    } else {
        currency.each(function (index) {
            var elem = $(this).contents().filter(function() {
                return this.nodeType === 3;
            });
            var text = elem.text();
            elem[0].nodeValue = text.replace("£", "€");
        });
    }
});

FIDDLE

Be aware that trim() will require a polyfill for some old browsers, or you could just use jQuery's $.trim() instead.

Just for fun, here's a shorter more efficient version:

$('#inv_currency').on('change', function () {
    $('.currency').each(function (index, elm) {
        var elem = $(elm).contents().filter(function () {
            return this.nodeType === 3;
        }).get(0);
        elem.nodeValue = elem.nodeValue.replace(/(\€|\£)/g, function(x) {
            return x == '€' ? '£' : '€';
        });
    });
});

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388
  • You could go [even shorter](http://jsfiddle.net/TEJBe/4/) given the ` – Brad Christie Feb 18 '13 at 16:20
  • @BradChristie - not sure I get it. I see what you did with the object, but an example would be great. Just playing around now really, having fun shortening it ? – adeneo Feb 18 '13 at 16:23
0

Use other selector than $(this), it turns confusing sometimes.

martriay
  • 5,632
  • 3
  • 29
  • 39