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
319k29 gold badges410 silver badges392 bronze badges
asked Feb 18, 2013 at 15:50
2
  • Is the value ever "pound" ??? Commented Feb 18, 2013 at 15:54
  • Try changing the "pound" to actual value. Commented Feb 18, 2013 at 15:55

5 Answers 5

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).

answered Feb 18, 2013 at 15:57
Sign up to request clarification or add additional context in comments.

1 Comment

thanks for this, its my first encouter with text nodes, I like your solution
1
 if ($(this).val() == 'pound') {

to

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

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

answered Feb 18, 2013 at 15:55

Comments

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?

answered Feb 18, 2013 at 15:57

Comments

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

answered Feb 18, 2013 at 16:05

2 Comments

You could go even shorter given the <option> value is the symbol to be inserting... ;-)
@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 ?
0

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

answered Feb 18, 2013 at 15:54

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.