radiocaf
radiocaf

Reputation: 151

How to adapt my JavaScript to work with multiple rows and different value?

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

Answers (3)

Thriggle
Thriggle

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

Logar314159
Logar314159

Reputation: 503

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

http://jsfiddle.net/ewLsoyvh/

Upvotes: 1

digitalbs
digitalbs

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

Related Questions