CraZyDroiD
CraZyDroiD

Reputation: 7105

passing values to a function does not work when inside for loop

I'm mapping currencies from a json file and i render the mapped currencies to a component. I have a .php file like this

<div class="currency-switch-container" id="currency_container">
    <span style="font-size:12px;font-weight:bold">All currencies</span>
    <div id="currency-map" style="margin-top:15px"></div>
</div>

I refer the div in the above component in my js file as follows

let currencyMap = jQuery("#currency-map");

And when my jQuery document is ready i'm doing the following

jQuery(document).ready(function($) {
  $.getJSON('wp-content/themes/mundana/currency/currency.json', function(data) {
    for(let c in data){
      currencyMap.append(`<span onclick="onCurrencyClick(${data[c].abbreviation})"
      class="currency-item">
        <span>
           ${data[c].symbol}
        </span>
        <span>
          ${data[c].currency}
        </span>
      </span>`)
    }
});

}

and my function is like this

function onCurrencyClick(val){
  console.log("val",val);
  setCookie("booking_currency", val, 14);
}

Here the function does not work. But if i do not pass anything to the function it seems to work as i can see the log in the terminal.

Upvotes: 0

Views: 61

Answers (3)

Emiel Zuurbier
Emiel Zuurbier

Reputation: 20944

Instead of using the inline onclick, use event delegation. This means that you have a single event listener that handles all the events from the children and grandchildren. The modification is a very minor one seeing the example here below.

A reason for doing this is that you keep your JavaScript inside your JS file. Like now, you encounter a JS error and have to look for it in your HTML. That can get very confusing. Also however inline onclick listeners are valid, they are outdated and should be avoided unless there is absolutely no other way. Compare it with using !important in CSS, same goes for that.

function onCurrencyClick(event){
  var val = $(this).val();
  setCookie("booking_currency", val, 14);
}

currencyMap.on('click', '.currency-item', onCurrencyClick);

This example takes the val that you try to insert from the value attribute from the clicked .current-item. <span> elements don't have such an attribute, but a <button> does and is a much more suitable element for it expects to be interacted with. It is generally a good practice to use clickable elements for purposes such as clicking.

In the example below you see the button being used and the abbreviation value being output in the value attribute of the <button> element and can be read from the onCurrencyClick function.

jQuery(document).ready(function($) {
  $.getJSON('wp-content/themes/mundana/currency/currency.json', function(data) {
    for(let c in data){
      currencyMap.append(`
        <button value="${data[c].abbreviation}" class="currency-item">
          <span>
            ${data[c].symbol}
          </span>
          <span>
            ${data[c].currency}
          </span>
        </button>
      `)
    }
});

Upvotes: 1

Dickens A S
Dickens A S

Reputation: 4054

onclick will not work for a dynamically added div tag

Yo should follow jQuery on event

Refer: jQuery on
Stackoverflow Refer: Dynamic HTML Elements

Upvotes: 0

Ranjeet Singh
Ranjeet Singh

Reputation: 61

Hi your expression ${data[c].abbreviation} will put the value into function string without string quotes i.e. the resultant would be onCurrencyClick(abbreviation) while it should be onCurrencyClick('abbreviation'). please use onclick="onCurrencyClick('${data[c].abbreviation}')" instead.

Upvotes: 1

Related Questions