Reputation: 151
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/
Upvotes: 0
Views: 112
Reputation: 7059
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);
Upvotes: 1
Reputation: 503
I think your only problem is: if (strUser = 'GBP')
, this should be: if (strUser == 'GBP')
(must use double equals ==)
Upvotes: 1
Reputation: 11
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);
})();
Upvotes: 1