Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not assume that lack of data-currency attribute means element is formatted in oldCurrency #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 16 additions & 10 deletions README.md
Expand Up @@ -6,7 +6,7 @@ jquery.currencies.js

## Description

jquery.currencies.js expands the currencies.js library provided by Shopify and has to be used in conjunction with it.
jquery.currencies.js expands the currencies.js library provided by Shopify and has to be used in conjunction with it.

While currencies.js allows you to convert a money amount from one currency to another, jquery.currencies.js provides a function that converts all money amounts on a web page and shows a _formatted_ result, with currency symbol and descriptor.

Expand All @@ -25,43 +25,49 @@ To save a picked currency to a cookie, use the following line of code, passing t
Currency.cookie.write('CAD');

To read the currency code saved to your 'currencies' cookie, use the following code:

var cookieCurrency = Currency.cookie.read();

The above will return the currency code, or will return null if the cookie does not exist.

To convert formatted money (with or without the currency code and descriptor) to formatted money in another currency use this:

Currency.convertAll(oldCurrency, newCurrency, selector, format);

The parameters _oldCurrency_ and _newCurrency_ must be set to the 3-letter currency codes of the FROM and TO currencies.

The parameter _selector_ is a CSS selector that tells the function where to find the money on the page. It is optional. If it is not used, the function will look for all span elements on the page with a class attribute set to 'money', and will convert the money in those elements.

So, using it without _selector_ is the same as calling the function like so:

Currency.convertAll('CAD', 'USD', 'span.money');

The parameter __format__ is optional and can take on the value 'money_format' or 'money_with_currency_format'.

Calling the function without _format_ is the same as calling the function like so:

Currency.convertAll('CAD', 'USD', 'span.money', 'money_with_currency_format');


The parameter __shopCurrency__ is optional and should be set to the 3-letter currency code that your shop is set to (i.e. what unconverted currencies are originally rendered as).

Without this parameter, it is assumed currency elements are already expressed in _oldCurrency_ currency.
If you add new currency elements to the DOM between conversions, this may cause conversion bugs.
To use without _selector_ and _format_, call like this Currency.convertAll('CAD', 'USD', undefined, undefined, "AUD");

Important: the convertAll method updates the 'currencies' cookie with _newCurrency_ and it also sets a global property that remembers what the current currency is: Currency.currentCurrency. Why? The cookie needs only be read once, ie. when the page loads, and one must keep a copy of the old value to send both old and new values to the converting drone.

## Optional global settings

Add the following line of JavaScript before you own code, if you do not want the formatted money to show the currency descriptor:

Currency.format = 'money_format';

If you don't use the above line of code, the formatted money will be showing both the currency symbol and descriptor, i.e. it will show $20.00 USD instead of $20.00.

If you want to use a different name for your cookie, use this:

Currency.cookie.name = 'my_awesome_cookie_name';

If you don't use the above line of code, the name of your cookie will be 'currencies'.

## Dependencies
Expand All @@ -75,8 +81,8 @@ currencies.js must be included before jquery.currencies.min.js.
## Author

jquery.currencies.js was created and is maintained by Caroline Schnapp mllegeorgesand AT gmail DOT com.

## License

jquery.currencies.js and its minified version are covered by the MIT License.
http://www.opensource.org/licenses/mit-license.php
http://www.opensource.org/licenses/mit-license.php
64 changes: 64 additions & 0 deletions currencies.liquid
@@ -0,0 +1,64 @@
{% if settings.show_multiple_currencies %}

{{ "//cdn.shopify.com/s/javascripts/currencies.js" | script_tag }}
{{ "jquery.currencies.min.js" | asset_url | script_tag }}

<script>
Currency.format = '{{ settings.currency_format | default: 'money_with_currency_format' }}';
var shopCurrency = '{{ shop.currency }}';
/* Sometimes merchants change their shop currency, let's tell our JavaScript file */
Currency.moneyFormats[shopCurrency].money_with_currency_format = {{ shop.money_with_currency_format | strip_html | json }};
Currency.moneyFormats[shopCurrency].money_format = {{ shop.money_format | strip_html | json }};

/* Default currency */
var defaultCurrency = '{{ settings.default_currency | default: shop.currency }}';

/* Cookie currency */
var cookieCurrency = Currency.cookie.read();
/* Fix for customer account pages */
jQuery('span.money span.money').each(function() {
jQuery(this).parents('span.money').removeClass('money');
});
/* Saving the current price */
jQuery('span.money').each(function() {
jQuery(this).attr('data-currency-{{ shop.currency }}', jQuery(this).html());
});
// If there's no cookie.
if (cookieCurrency == null) {
if (shopCurrency !== defaultCurrency) {
Currency.convertAll(shopCurrency, defaultCurrency);
}
else {
Currency.currentCurrency = defaultCurrency;
}
}
// If the cookie value does not correspond to any value in the currency dropdown.
else if (jQuery('[name=currencies]').size() && jQuery('[name=currencies] option[value=' + cookieCurrency + ']').size() === 0) {
Currency.currentCurrency = shopCurrency;
Currency.cookie.write(shopCurrency);
}
else if (cookieCurrency === shopCurrency) {
Currency.currentCurrency = shopCurrency;
}
else {
Currency.convertAll(shopCurrency, cookieCurrency);
}
jQuery('[name=currencies]').val(Currency.currentCurrency).change(function() {
var newCurrency = jQuery(this).val();
Currency.convertAll(Currency.currentCurrency, newCurrency, undefined, undefined, shopCurrency);
jQuery('.selected-currency').text(Currency.currentCurrency);
});
var original_selectCallback = window.selectCallback;
var selectCallback = function(variant, selector) {
original_selectCallback(variant, selector);
Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val(), undefined, undefined, shopCurrency);
jQuery('.selected-currency').text(Currency.currentCurrency);
};
$('body').on('ajaxCart.afterCartLoad', function() {
Currency.convertAll(shopCurrency, jQuery('[name=currencies]').val());
jQuery('.selected-currency').text(Currency.currentCurrency);
});
jQuery('.selected-currency').text(Currency.currentCurrency);
</script>

{% endif %}
32 changes: 22 additions & 10 deletions jquery.currencies.js
Expand Up @@ -17,7 +17,7 @@ jQuery.cookie=function(b,j,m){if(typeof j!="undefined"){m=m||{};if(j===null){j="
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
*/

if (typeof Currency === 'undefined') {
var Currency = {};
Expand Down Expand Up @@ -570,12 +570,12 @@ Currency.formatMoney = function(cents, format) {
}
return formatString.replace(placeholderRegex, value);
};

Currency.currentCurrency = '';

Currency.format = 'money_with_currency_format';

Currency.convertAll = function(oldCurrency, newCurrency, selector, format) {
Currency.convertAll = function(oldCurrency, newCurrency, selector, format, shopCurrency) {
jQuery(selector || 'span.money').each(function() {
// If the amount has already been converted, we leave it alone.
if (jQuery(this).attr('data-currency') === newCurrency) return;
Expand All @@ -585,17 +585,29 @@ Currency.convertAll = function(oldCurrency, newCurrency, selector, format) {
}
else {
// Converting to Y for the first time? Let's get to it!

// If there is no data-currency attribute on the element being converted,
// the currency has not been converted yet and is probably in the regular shop currency.
// If we assume the element is in oldCurrency when it's really in shopCurrency,
// things can go wrong.
// This might occur when a new currency element is added to the DOM between conversions
var fromCurrency = oldCurrency;
if (jQuery(this).attr('data-currency') == null) {
// For this iteration we will use the shopDefaultCurrency instead of the requested oldCurrency.
fromCurrency = shopCurrency || oldCurrency; // If shopDefaultCurrency was not passed in, we will have to use oldCurrency anyway
}

var cents = 0.0;
var oldFormat = Currency.moneyFormats[oldCurrency][format || Currency.format] || '{{amount}}';
var oldFormat = Currency.moneyFormats[fromCurrency][format || Currency.format] || '{{amount}}';
var newFormat = Currency.moneyFormats[newCurrency][format || Currency.format] || '{{amount}}';
if (oldFormat.indexOf('amount_no_decimals') !== -1) {
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10)*100, oldCurrency, newCurrency);
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10)*100, fromCurrency, newCurrency);
}
else if (oldCurrency === 'JOD' || oldCurrency == 'KWD' || oldCurrency == 'BHD') {
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10)/10, oldCurrency, newCurrency);
else if (fromCurrency === 'JOD' || fromCurrency == 'KWD' || fromCurrency == 'BHD') {
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10)/10, fromCurrency, newCurrency);
}
else {
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10), oldCurrency, newCurrency);
else {
cents = Currency.convert(parseInt(jQuery(this).html().replace(/[^0-9]/g, ''), 10), fromCurrency, newCurrency);
}
var newFormattedAmount = Currency.formatMoney(cents, newFormat);
jQuery(this).html(newFormattedAmount);
Expand All @@ -606,4 +618,4 @@ Currency.convertAll = function(oldCurrency, newCurrency, selector, format) {
});
this.currentCurrency = newCurrency;
this.cookie.write(newCurrency);
};
};