简体   繁体   中英

How do I make getSelectedCurrency run only when the select element has been populated with options

I'm trying to return the currently selected option from the getSelectedCurrency function by default the select currency option is selected but disabled. Now I'm trying to make the function return the currently selected option only when there are other options in the select elements and when the select element changes.

I tried adding an onchange Event listener but I can't return anything to the function itself as eventlisteners return undefined by default, so by the time getSelectedCurrency is called, it returns nothing which is not what I want.

I also tried to add the onchange event listener to the populateCurrencies function so as to register the event early enough.... but when I call getSelectedCurrency() right after declaring it (and after declaring populateCurrencies() ) it returns only the default (ie select currency text)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />

    <title>Mini App</title>

    <style>
        body{
            background-color:#fff;
            margin:15px;
            }
       .select{
            margin-top:50px;
        }
       .conversion{
            margin:25px 0px;
        }
       .btn{
            width:100%;
            font-size:1.2rem;
            padding:1rem;
           }
    </style>
</head>
<body>
    <h1>Naira Converted</h1>
    <div class="select-currency select">
        <select class="select-text">
            <option selected disabled>Select Currency</option>
        </select>
        <button type="submit" class="btn">In Naira</button>
        <div class="conversion mdc-elevation--z3"></div> 
        <div class="messages"></div>
    </div>
<script>
const currencies = [{
    id: 'USD', name: 'US Dollars'
  }, {
    id: 'UGX', name: 'Ugandan Shillings'
  }, {
    id: 'KES', name: 'Kenyan Shillings'
  }, {
    id: 'GHS', name: 'Ghanian Cedi'
  }, {
    id: 'ZAR', name: 'South African Rand'
  }];

  const apiBase = 'https://free.currencyconverterapi.com/api/v6/';
  const api = (currency) => `
    ${apiBase}convert?q=${currency}_NGN&compact=ultra
  `;

  const toast = (msg) => {
    const toastr = document.querySelector('.messages');
    if(!toastr) return;

    toastr.textContent = msg;
    if(!toastr.classList.contains('on')) {
      toastr.classList.add('on');
    }
  };

  const doneToasting = () => {
    const toastr = document.querySelector('.messages');
    if(!toastr) return;

    toastr.textContent = '';
    toastr.classList.remove('on');
  };

  const conversionSucceeded = (apiResponse) => {
    if(!apiResponse) {
      toast(`nothing to display ...`);
      return;
    }

    const [value] = Object.values(apiResponse)

    const btn = document.querySelector('button');
    btn.removeAttribute('disabled');

    const display = document.querySelector('.conversion');
    const formatter = new Intl.NumberFormat(
      'en-NG', { style: 'currency', currency: 'NGN' }
    );

    display.textContent = formatter.format(value);
    doneToasting();
  };
 // declare populateCurrencies here      
  const populateCurrencies = ()=>{
    currencies.forEach((x)=>{
      let elt = document.querySelector('.select-text');
      let newElt = document.createElement('option');
      let newText = document.createTextNode(x.name);
      newElt.appendChild(newText);
      newElt.setAttribute('value',x.id);
      elt.appendChild(newElt);
    })
      let elt = document.querySelector('.select-text');
    elt.addEventListener('change',()=>{
       let currentlySelected =document.querySelector('[selected]');
       currentlySelected.removeAttribute('selected');
       elt.selectedOptions[0].setAttribute('selected','');
      console.log(getSelectedCurrency());
      },false)
    }
   const getSelectedCurrency=()=>{
    // here, determine and return the selected value 
    // of the SELECT element
    let currentlySelected= document.querySelector('.select-text');
    let value= currentlySelected.selectedOptions[0].textContent;
    return(value) ;
  };
  const selected = getSelectedCurrency();
  console.log(selected);
  const convert = (event) => {
    toast(`preparing to convert ...`);

    const btn = event ? 
          event.target : document.querySelector('button');

    const selected = getSelectedCurrency();

    if(!selected || selected.trim() === '' 
       || !currencies.map(c => c.id).includes(selected)) return;

    btn.setAttribute('disabled', 'disabled');
    toast(`converting ...`);

    const endpoint = api(selected);

    // make a GET fetch call to the endpoint
    // variable declared above, convert the response to JSON,
    // then call conversionSucceeded and pass the JSON data to it
  };

  const startApp = () => {
    // call populateCurrencies here
    populateCurrencies();
    // add a click listener to the button here
    document.querySelector('button').addEventListener('click',(event)=>       
    {convert(event)},false);
  };
  startApp();
        </script>
     </body>
</html>

I expect that calling getSelectedCurrency should return the currently selected option and when a change occurs it should also return that change also but it returns only the default.

Done a bunch of tidy up here, you were selecting controls multiple times and also getting the text or your select rather than the value for conversion.

Now its ready for you to add your API call code.

 const currencies = [{ id: 'USD', name: 'US Dollars' }, { id: 'UGX', name: 'Ugandan Shillings' }, { id: 'KES', name: 'Kenyan Shillings' }, { id: 'GHS', name: 'Ghanian Cedi' }, { id: 'ZAR', name: 'South African Rand' }]; const apiBase = 'https://free.currencyconverterapi.com/api/v6/'; const api = (currency) => `${apiBase}convert?q=${currency}_NGN&compact=ultra`; const toast = (msg) => { const toastr = document.querySelector('.messages'); if (!toastr) return; toastr.innerText = msg; toastr.classList.add('on'); }; const doneToasting = () => { const toastr = document.querySelector('.messages'); if (!toastr) return; toastr.innerText = ''; toastr.classList.remove('on'); }; const conversionSucceeded = (apiResponse) => { if (!apiResponse) { toast(`nothing to display ...`); return; } const [value] = Object.values(apiResponse) const btn = document.querySelector('button'); btn.removeAttribute('disabled'); const display = document.querySelector('.conversion'); const formatter = new Intl.NumberFormat( 'en-NG', { style: 'currency', currency: 'NGN' } ); display.innerText = formatter.format(value); doneToasting(); }; // declare populateCurrencies here const populateCurrencies = () => { let elt = document.querySelector('.select-text'); currencies.forEach((x) => { let newElt = document.createElement('option'); newElt.text = x.name; newElt.value = x.id; elt.add(newElt); }) elt.addEventListener('change', () => { console.log(getSelectedCurrency()); }, false) }; const getSelectedCurrency = () => { // here, determine and return the selected value // of the SELECT element let currentlySelected = document.querySelector('.select-text'); let value = currentlySelected.selectedOptions[0].value; return (value); }; const selected = getSelectedCurrency(); console.log(selected); const convert = (event) => { toast(`preparing to convert ...`); const btn = event ? event.target : document.querySelector('button'); const selected = getSelectedCurrency(); toast(`converting for currency: ${selected}`); if (!selected || selected.trim() === '' || !currencies.map(c => c.id).includes(selected)) return; btn.setAttribute('disabled', 'disabled'); toast(`converting ...`); const endpoint = api(selected); // Need to add your API call now. console.log(endpoint); // make a GET fetch call to the endpoint // variable declared above, convert the response to JSON, // then call conversionSucceeded and pass the JSON data to it }; const startApp = () => { // call populateCurrencies here populateCurrencies(); // add a click listener to the button here document.querySelector('button').addEventListener('click', (event) => { convert(event) }, false); }; startApp(); 
 body { background-color: #fff; margin: 15px; } .select { margin-top: 50px; } .conversion { margin: 25px 0px; } .btn { width: 100%; font-size: 1.2rem; padding: 1rem; } 
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" /> <title>Mini App</title> </head> <body> <h1>Naira Converted</h1> <div class="select-currency select"> <select class="select-text"> <option selected disabled>Select Currency</option> </select> <button type="submit" class="btn">In Naira</button> <div class="conversion mdc-elevation--z3"></div> <div class="messages"></div> </div> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM