0

I have a span that works to display a currency symbol at the start of a price input box that changes based on what currency is selected in a dropdown box. These work by calling notEmpty() with an onChange event.

My code was:

function notEmpty(){
    var e = document.getElementById("currencysel");
    var strUser = e.options[e.selectedIndex].value;
    var strUser2 = " " + strUser;
    document.getElementById('currencysym').innerHTML = strUser2;
}

notEmpty()
document.getElementById("currencysel").onchange = notEmpty;

I had to add the   to properly align the symbol in the price text box.

This worked perfectly until I made two changes, I no longer use the actual currency symbol (£, $, €) as the value because MySQL does not like the £ symbol, I now use GBP, USD and EUR. The second change is with each row, I load a form that includes both the currencysel dropdown and the currencysym span. Now fixing this is easy, I can just append the row ID to the end of the currencysel and currencysym IDs, so an example row may have currencysel6 and currencysym6, but how do I get the JavaScript to still recognize these despite the numbers on the end?

For the first issue, I tried:

function notEmpty(){
    var e = document.getElementById('currencysel');
    var strUser = e.options[e.selectedIndex].value;
    if (strUser = 'GBP'){
        strUser2 = ' £'
    } else if (strUser = "USD"){
        strUser2 = ' $'
    } else if (strUser = "EUR"){
        strUser2 = ' €'
    }
    document.getElementById('currencysym').innerHTML = strUser2;
}

But this didn't work.

The second issue I didn't have a single clue, which is where I'm hoping to receive your assistance.

Fiddle: http://jsfiddle.net/66co5kfo/

6
  • How is your markup? Is it a table? Commented Nov 12, 2015 at 17:31
  • For the form, yes, a table, which is loaded in a modal if that is any help? Commented Nov 12, 2015 at 17:32
  • Can you provide us a jsfiddle to test your code? Commented Nov 12, 2015 at 17:37
  • I have now added the fiddle @Logar314159 that is the code working with the Dropdown values being the symbols (£, $, €), and not the currency codes (GBP, USD, EUR). I also need to make it so I can have several of these forms on the page and the JavaScript Code can discern between them. If that makes sense? Commented Nov 12, 2015 at 17:45
  • 2
    you could use the pound euro and dollar sign but use the html codes: £ € $ as for discerning between the forms, give them unique ids then you should be fine. Commented Nov 12, 2015 at 17:49

3 Answers 3

1

What you can do is access the elements by class name instead of by ID. You'll just need to provide a common class name on all the relevant select elements so you can access them. (And do the same thing for the corresponding span elements.

Then instead of .getElementById() you can use .querySelector() and .querySelectorAll() along with CSS selectors (such as ".className" to get an element with a class of "className").

Check out the example code below to see how you can access and attach events to multiple different elements without knowing their IDs.

// get all the containing elements by classname
var pickers = document.querySelectorAll(".currencyPicker");

// loop through all those containers
var i = pickers.length;
while (i--) {
  // this is an immediately executing function expresion which creates a closure
  // the closure allows the event listener to access the span and select elements
  (function(span, select) {
    // attach the change event to the select element  
    select.addEventListener("change", function() {
      notEmpty(span, select);
    });
  })(pickers[i].querySelector(".currencysym"), pickers[i].querySelector(".currencysel"));
}

function notEmpty(spanToUpdate, select) {
  switch(select.value){
      case "USD":
        spanToUpdate.innerHTML = "$";
        break;
      case "GBP":
        spanToUpdate.innerHTML = "£";
        break;
      case "EUR":
        spanToUpdate.innerHTML = "€";
        break;
  }
  
}
<table>
  <tr>
    <td>
      <div class="currencyPicker">
        <select class="currencysel">
          <options>
            <option value="USD">$</option>
            <option value="GBP">£</option>
            <option value="EUR">€</option>
          </options>
        </select>
        <span class="currencysym">$</span>
        <input type="text" />
      </div>
    </td>
  </tr>

  <tr>
    <td>
      <div class="currencyPicker">
        <select class="currencysel">
          <options>
            <option value="USD">$</option>
            <option value="GBP">£</option>
            <option value="EUR">€</option>
          </options>
        </select>
        <span class="currencysym">$</span>
        <input type="text" />
      </div>
    </td>
  </tr>
  <tr>
    <td>
      <div class="currencyPicker">
        <select class="currencysel">
          <options>
            <option value="USD">$</option>
            <option value="GBP">£</option>
            <option value="EUR">€</option>
          </options>
        </select>
        <span class="currencysym">$</span>
        <input type="text" />
      </div>
    </td>
  </tr>
</table>

As I mentioned in the code comments, the following pattern is used to create an immediately executing function expression (IIFE), which is an advanced but handy JavaScript concept.

(function(){
    // code
})();

This is useful in a loop because you can pass parameters into the function expression to get snapshots of variable values, which you can then pass on to other functions (which might not execute right away, as in the case of event handlers) as needed.

originalVariable = arr[i];
(function(copiedVariable){
    // code that uses copiedVariable
})(originalVariable);
Sign up to request clarification or add additional context in comments.

7 Comments

Hi @Thriggle, for this to work, do I have to have the currencysel before the currencysym? Also, I want the symbol to show up next to the price, rather than the currency code.
@radiocaf The order shouldn't matter, but notice that I did wrap up the currencysel and currencysym elements in a div with a class of currencyPicker. The code queries all the currencyPickers, then queries each of those results for the inner currencysel/currencysym elements.
@radiocaf I also updated the code with an example of a switch statement for handling the currency symbol/abbreviation swap.
thank you, it must be something I'm doing wrong, does the code rely on anything else? I only ask in case something to do with my layout is stopping it from running.
I finally got it to work, without having to add the script to the while loop so it gets repeated with every row. I found adding the script after the while loop works. I imagine having the script above the loop or in the header doesn't work because maybe the script starts before the PHP or server is processed and the rows are added? I am probably wrong, but that's the only explanation I can think of. Thanks Thriggle.
|
1

I created a plunker for your solution. This code does not require any additional Javascript libraries, but does require bootstrap CSS. It can also be done with plain text if you did not want to use CSS.

http://plnkr.co/edit/V0GDRY?p=preview

HTML

<form class="form-inline">
  <div class="form-group">
    <label class="form-label">Select a currency</label>
    <select class="form-control" id="currencyDropdown">
      <option value="glyphicon-gbp">£</option>
      <option value="glyphicon-usd">$</option>
      <option value="glpyhicon-euro">€</option>
    </select>
  </div>
  <div class="form-group">
    <label class="form-label">Enter a Price</label>
    <div class="input-group">
      <div class="input-group-addon glyphicon glyphicon-gbp" id="currencySymbol"></div>
      <input type="text" class="form-control" id="exampleInputAmount" placeholder="Amount">
    </div>
  </div>
  <button type="submit" class="btn btn-primary">Submit Price</button>
</form>

JS

 function changeCurrencyType (symbolClass) {
  var symbol = document.getElementById('currencySymbol');

  symbol.className = 'input-group-addon glyphicon ' + symbolClass;
}

(function () {
  var currencyDropdown = document.getElementById('currencyDropdown');  

  currencyDropdown.addEventListener('change', function () {
    var symbolClass = currencyDropdown.options[currencyDropdown.selectedIndex].value;

    changeCurrencyType(symbolClass);
  }, false);
})();

2 Comments

If you need this in a table, I could provide the HTML, but the mechanics are the same.
If you have the option, you should use a declarative framework like Angular or Ember when developing. These frameworks make developing much easier, and less stateful in situations like this.
1

I think your only problem is: if (strUser = 'GBP'), this should be: if (strUser == 'GBP') (must use double equals ==)

http://jsfiddle.net/ewLsoyvh/

Comments

Your Answer

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.