3

I have a currency selector function that automatically detects the location of the user and updates the website's currency & the select location both on load and when the #currency_form is changed.

The problem is that when I run the code, the page infinately refreshes. How do I change my code so that the currency and selector is updated on load and if the user changes the selector value from the #currency_form?

Submitting the form refreshes the page and updates the currency / location. This needs to happen on load where mycurrency matches the location & when the select is changed since it will change the currencies that are displayed on the site.

window.addEventListener('DOMContentLoaded', function() {
 (function($) {
    $(document).ready(function(e) {
      var currmap = {"BD": "BDT", "BE": "EUR", "BF": "XOF", "BG": "BGN", "BA": "BAM", "BB": "BBD", "WF": "XPF", "BL": "EUR", "BM": "BMD", "BN": "BND", "BO": "BOB", "BH": "BHD", "BI": "BIF", "BJ": "XOF", "BT": "BTN", "JM": "JMD", "BV": "NOK", "BW": "BWP", "WS": "WST", "BQ": "USD", "BR": "BRL", "BS": "BSD", "JE": "GBP", "BY": "BYR", "BZ": "BZD", "RU": "RUB", "RW": "RWF", "RS": "RSD", "TL": "USD", "RE": "EUR", "TM": "TMT", "TJ": "TJS", "RO": "RON", "TK": "NZD", "GW": "XOF", "GU": "USD", "GT": "GTQ", "GS": "GBP", "GR": "EUR", "GQ": "XAF", "GP": "EUR", "JP": "JPY", "GY": "GYD", "GG": "GBP", "GF": "EUR", "GE": "GEL", "GD": "XCD", "GB": "GBP", "GA": "XAF", "SV": "USD", "GN": "GNF", "GM": "GMD", "GL": "DKK", "GI": "GIP", "GH": "GHS", "OM": "OMR", "TN": "TND", "JO": "JOD", "HR": "HRK", "HT": "HTG", "HU": "HUF", "HK": "HKD", "HN": "HNL", "HM": "AUD", "VE": "VEF", "PR": "USD", "PS": "ILS", "PW": "USD", "PT": "EUR", "SJ": "NOK", "PY": "PYG", "IQ": "IQD", "PA": "PAB", "PF": "XPF", "PG": "PGK", "PE": "PEN", "PK": "PKR", "PH": "PHP", "PN": "NZD", "PL": "PLN", "PM": "EUR", "ZM": "ZMK", "EH": "MAD", "EE": "EUR", "EG": "EGP", "ZA": "ZAR", "EC": "USD", "IT": "EUR", "VN": "VND", "SB": "SBD", "ET": "ETB", "SO": "SOS", "ZW": "ZWL", "SA": "SAR", "ES": "EUR", "ER": "ERN", "ME": "EUR", "MD": "MDL", "MG": "MGA", "MF": "EUR", "MA": "MAD", "MC": "EUR", "UZ": "UZS", "MM": "MMK", "ML": "XOF", "MO": "MOP", "MN": "MNT", "MH": "USD", "MK": "MKD", "MU": "MUR", "MT": "EUR", "MW": "MWK", "MV": "MVR", "MQ": "EUR", "MP": "USD", "MS": "XCD", "MR": "MRO", "IM": "GBP", "UG": "UGX", "TZ": "TZS", "MY": "MYR", "MX": "MXN", "IL": "ILS", "FR": "EUR", "IO": "USD", "SH": "SHP", "FI": "EUR", "FJ": "FJD", "FK": "FKP", "FM": "USD", "FO": "DKK", "NI": "NIO", "NL": "EUR", "NO": "NOK", "NA": "NAD", "VU": "VUV", "NC": "XPF", "NE": "XOF", "NF": "AUD", "NG": "NGN", "NZ": "NZD", "NP": "NPR", "NR": "AUD", "NU": "NZD", "CK": "NZD", "XK": "EUR", "CI": "XOF", "CH": "CHF", "CO": "COP", "CN": "CNY", "CM": "XAF", "CL": "CLP", "CC": "AUD", "CA": "CAD", "CG": "XAF", "CF": "XAF", "CD": "CDF", "CZ": "CZK", "CY": "EUR", "CX": "AUD", "CR": "CRC", "CW": "ANG", "CV": "CVE", "CU": "CUP", "SZ": "SZL", "SY": "SYP", "SX": "ANG", "KG": "KGS", "KE": "KES", "SS": "SSP", "SR": "SRD", "KI": "AUD", "KH": "KHR", "KN": "XCD", "KM": "KMF", "ST": "STD", "SK": "EUR", "KR": "KRW", "SI": "EUR", "KP": "KPW", "KW": "KWD", "SN": "XOF", "SM": "EUR", "SL": "SLL", "SC": "SCR", "KZ": "KZT", "KY": "KYD", "SG": "SGD", "SE": "SEK", "SD": "SDG", "DO": "DOP", "DM": "XCD", "DJ": "DJF", "DK": "DKK", "VG": "USD", "DE": "EUR", "YE": "YER", "DZ": "DZD", "US": "USD", "UY": "UYU", "YT": "EUR", "UM": "USD", "LB": "LBP", "LC": "XCD", "LA": "LAK", "TV": "AUD", "TW": "TWD", "TT": "TTD", "TR": "TRY", "LK": "LKR", "LI": "CHF", "LV": "EUR", "TO": "TOP", "LT": "LTL", "LU": "EUR", "LR": "LRD", "LS": "LSL", "TH": "THB", "TF": "EUR", "TG": "XOF", "TD": "XAF", "TC": "USD", "LY": "LYD", "VA": "EUR", "VC": "XCD", "AE": "AED", "AD": "EUR", "AG": "XCD", "AF": "AFN", "AI": "XCD", "VI": "USD", "IS": "ISK", "IR": "IRR", "AM": "AMD", "AL": "ALL", "AO": "AOA", "AQ": "", "AS": "USD", "AR": "ARS", "AU": "AUD", "AT": "EUR", "AW": "AWG", "IN": "INR", "AX": "EUR", "AZ": "AZN", "IE": "EUR", "ID": "IDR", "UA": "UAH", "QA": "QAR", "MZ": "MZN"};
      $.getJSON('//freegeoip.app/json/', function(location) {
        if(location.country_code){
          var mycurrency = currmap[location.country_code];
          if(mycurrency){
          $("#currency_form select").val(mycurrency);
          $("#currency_form select").change();
          }
        }
      });
    });
  })(jQuery);
});

$('#currency_form select').on('change', function(e) {
  $('#currency_form').submit();
  console.log('cur change: ', $(this).val());
});
Kyle Underhill
  • 89
  • 15
  • 43
  • 1
    `addEventListener('DOMContentLoaded'`, `function($) {` and `$(document).ready(function() ` are pretty much equivalent (2 and 3 are the same thing). You have an overkill triple mechanism to check that your page has loaded. Also, I think `$('#currency_form').submit()` will reload the page, because the default behaviour when submitting a form is to reload the page. You need to prevent reloading with `event.preventDefault()` – Jeremy Thille Jun 16 '21 at 14:47
  • Thanks Jeremy. How would I incorporate the `event.preventDefault()` with my code? – Kyle Underhill Jun 16 '21 at 14:53
  • 1
    Pass `submit()` a function that returns false : https://stackoverflow.com/questions/6462143/prevent-default-on-form-submit-jquery – Jeremy Thille Jun 16 '21 at 14:57
  • I can't seem to figure it out. Would you be able to provide a solution in an answer and I can mark it answered? – Kyle Underhill Jun 16 '21 at 15:38
  • Can you put the currency form html in your quesiton? What is the purpose of submitting that form? To change something on the page or to reload the page or to go to another page? – Kinglish Jun 18 '21 at 15:35
  • Submitting the form refreshes the page and updates the currency / location. This needs to happen on load where `mycurrency` matches the location & when the `select` is changed since it will change the currencies that are displayed on the site. – Kyle Underhill Jun 18 '21 at 15:39
  • OK, got that. Are you also including this tag in your theme? https://shopify.dev/tutorials/customize-theme-support-multiple-currencies#the-country-selector – Kinglish Jun 18 '21 at 18:11
  • No I used the form from the YouTube video: `{% form 'currency' %} {{ form | currency_selector }} {% endform %}` which creates the shopify selector that has the id `#currency_form` – Kyle Underhill Jun 18 '21 at 18:28

2 Answers2

0

I guess you should prevent the reloading of the page by passing a function that returns false to .submit() :

$('#currency_form').submit(function(){
    return false;
});
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63
0

As was mentioned, you were doubling up your onload mechanisms. Additionally your currmap variable was not a valid object. Object need key/value pairs, so that was erroring out. I made it an array since you reference it with square bracket notation underneath. To test if a given value exists in an array, use array.includes(value) which will return a boolean. Then the location.country_code is actually US for the US, rather than USD, so I made the select menu have US as the value and USD as the option display. Finally, the way you pre-selected the select option was not correct. You want to reference the element, find the option with the value you want (which returns an index) and then set the attr('selected', true)

I commented out the submit() since it's unclear what that does. Once you clear up that question, I can complete this answer, but otherwise, this should get you a working start. If this //freegeoip.app/json/ select menu check/submit was in a reusable header or script file, it would run every time a page was loaded and cause an infinite reload loop.

$(document).ready(function() {
  var currmap = ["US", "GBP"];
  $.getJSON('//freegeoip.app/json/', function(location) {
    if (location.country_code && currmap.includes(location.country_code)) {
      $("#currency_form select").find("option[value='" + location.country_code + "']").attr("selected", true);
      //$('#currency_form').submit();
    }
  });
});

$('#currency_form select').on('change', function() {
  //$('#currency_form').submit();
  console.log('cur change: ', $(this).val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<form id='currency_form'>
  <select name='currency'>
    <option>Choose a currency</option>
    <option value="US">USD</option>
    <option value="GBP">GBP</option>
  </select>
</form>
Kinglish
  • 23,358
  • 3
  • 22
  • 43
  • Submitting the form updates the currency to match the location on Shopify. I am trying to have the currency be auto-detected based on the user's location on load while also be updated if the user manually changes it from the `select`. – Kyle Underhill Jun 18 '21 at 16:21
  • Yes, but does it need to submit - and if so, is that submit calling an ajax function or is it supposed to post to another page? – Kinglish Jun 18 '21 at 16:28
  • I'm not sure how it works in Shopify but the page refreshes when the form is submitted and the page loads in the currency on the selected location. – Kyle Underhill Jun 18 '21 at 16:36
  • Ok. can you show your html of the form that contains this country select element? Basically if we're submitting the form and it's going to the same page we need to detect that it's already been submit or it's going to go inifinite again. This doesn't feel right. I wish I could see the whole context of what you're trying to do here. – Kinglish Jun 18 '21 at 16:55
  • I was following the steps at the url but also trying to incorporate the currency switcher from here: https://www.youtube.com/watch?v=LMaAphPbr4A Article: https://easycodeguide.com/how-to-auto-change-currency-based-on-location-in-shopify.html – Kyle Underhill Jun 18 '21 at 16:58
  • Tell me more about the JSON file you said may be causing the infinite loop. I currently have the code as a snippet injected into my theme.liquid file before closingtag. – Kyle Underhill Jun 20 '21 at 22:38