-
-
Save stewartknapman/8d8733ea58d2314c373e94114472d44c to your computer and use it in GitHub Desktop.
var Shopify = Shopify || {}; | |
// --------------------------------------------------------------------------- | |
// Money format handler | |
// --------------------------------------------------------------------------- | |
Shopify.money_format = "${{amount}}"; | |
Shopify.formatMoney = function(cents, format) { | |
if (typeof cents == 'string') { cents = cents.replace('.',''); } | |
var value = ''; | |
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/; | |
var formatString = (format || this.money_format); | |
function defaultOption(opt, def) { | |
return (typeof opt == 'undefined' ? def : opt); | |
} | |
function formatWithDelimiters(number, precision, thousands, decimal) { | |
precision = defaultOption(precision, 2); | |
thousands = defaultOption(thousands, ','); | |
decimal = defaultOption(decimal, '.'); | |
if (isNaN(number) || number == null) { return 0; } | |
number = (number/100.0).toFixed(precision); | |
var parts = number.split('.'), | |
dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands), | |
cents = parts[1] ? (decimal + parts[1]) : ''; | |
return dollars + cents; | |
} | |
switch(formatString.match(placeholderRegex)[1]) { | |
case 'amount': | |
value = formatWithDelimiters(cents, 2); | |
break; | |
case 'amount_no_decimals': | |
value = formatWithDelimiters(cents, 0); | |
break; | |
case 'amount_with_comma_separator': | |
value = formatWithDelimiters(cents, 2, '.', ','); | |
break; | |
case 'amount_no_decimals_with_comma_separator': | |
value = formatWithDelimiters(cents, 0, '.', ','); | |
break; | |
} | |
return formatString.replace(placeholderRegex, value); | |
}; |
@shriDeveloper Make sure the method is not inside a .liquid file or use {% raw %}{{ amount }}{% endraw %} in order to escape the Liquid parsing of {{ amount }} (which parses to an empty string)
As AlpineJS Magic property if anyone wants it -> https://gist.github.com/james0r/e5a02db44beba8b5fc447e78615c1eb7
This was exactly what I was looking for and works like a charm, you sir are an absolute legend.
there was a slight error in the code
function formatMoney(cents, format) {
if (typeof cents == 'string') { cents = cents.replace('.', ''); }
var value = '';
var placeholderRegex = /\{\{\s*(\w+)\s*\}\}/;
var formatString = (format || this.money_format);
function defaultOption(opt, def) {
return (typeof opt == 'undefined' ? def : opt);
}
function formatWithDelimiters(number, precision, thousands, decimal) {
precision = defaultOption(precision, 2);
thousands = defaultOption(thousands, ',');
decimal = defaultOption(decimal, '.');
if (isNaN(number) || number == null) { return 0; }
number = (number / 100.0).toFixed(precision);
var parts = number.split('.'),
dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands),
cents = parts[1] ? (decimal + parts[1]) : '';
return dollars + cents;
}
var match = formatString.match(placeholderRegex);
if (match) {
switch (match[1]) {
case 'amount':
value = formatWithDelimiters(cents, 2);
break;
case 'amount_no_decimals':
value = formatWithDelimiters(cents, 0);
break;
case 'amount_with_comma_separator':
value = formatWithDelimiters(cents, 2, '.', ',');
break;
case 'amount_no_decimals_with_comma_separator':
value = formatWithDelimiters(cents, 0, '.', ',');
break;
}
}
return formatString.replace(placeholderRegex, value);
};
paste this code into the theme.liquid
file
<script>
var Shopify = Shopify || {};
Shopify.money_format = "{{ shop.money_format }}";
</script>
paste this code into the JavaScript file
Shopify.formatMoney = function(cents, format) {
if (typeof cents == 'string') {
cents = cents.replace('.', '');
}
var value = '';
var placeholderRegex = /{{\s*(\w+)\s*}}/;
var formatString = (format || this.money_format);
function defaultOption(opt, def) {
return (typeof opt == 'undefined' ? def : opt);
}
function formatWithDelimiters(number, precision, thousands, decimal) {
precision = defaultOption(precision, 2);
thousands = defaultOption(thousands, ',');
decimal = defaultOption(decimal, '.');
if (isNaN(number) || number == null) {
return 0;
}
number = (number / 100.0).toFixed(precision);
var parts = number.split('.'),
dollars = parts[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + thousands),
cents = parts[1] ? (decimal + parts[1]) : '';
return dollars + cents;
}
switch (formatString.match(placeholderRegex)[1]) {
case 'amount':
value = formatWithDelimiters(cents, 2);
break;
case 'amount_no_decimals':
value = formatWithDelimiters(cents, 0);
break;
case 'amount_with_comma_separator':
value = formatWithDelimiters(cents, 2, '.', ',');
break;
case 'amount_no_decimals_with_comma_separator':
value = formatWithDelimiters(cents, 0, '.', ',');
break;
}
return formatString.replace(placeholderRegex, value);
};
Use the method like that anywhere you want
Shopify.formatMoney(120) // 120 is the number you want to convert into price.
TypeScript version that supports all currency formats in 2024:
/**
* Formats a number of cents into a currency string using a Shopify format
* string.
*
* https://help.shopify.com/en/manual/international/pricing/currency-formatting#currency-formatting-options
*
* Originally from: https://gist.github.com/stewartknapman/8d8733ea58d2314c373e94114472d44c
*
* @param cents - The number of cents to format.
* @param formatString - The format string to use.
* @returns The formatted currency string.
*/
export function shopifyFormatCurrency(cents: number, formatString: string) {
const placeholderRegex = /{{\s*(\w+)\s*}}/;
/**
* Formats a number of cents into a currency string using the provided
* precision, thousands separator, and decimal separator.
* @param number - The number of cents to format.
* @param precision - The number of decimal places to include.
* @param thousands - The character to use as the thousands separator.
* @param decimal - The character to use as the decimal separator.
* @returns The formatted currency string.
*/
function formatWithDelimiters(
number: number,
precision: number = 2,
thousands: string = ",",
decimal: string = ".",
) {
if (isNaN(number) || number == null) {
return "0";
}
const numString = (number / 100.0).toFixed(precision);
const parts = numString.split(".");
const dollars = parts[0].replace(
/(\d)(?=(\d\d\d)+(?!\d))/g,
"$1" + thousands,
);
const cents = parts[1] ? decimal + parts[1] : "";
return dollars + cents;
}
return formatString.replace(placeholderRegex, (match, placeholder) => {
switch (placeholder) {
case "amount":
// Ex. 1,134.65
return formatWithDelimiters(cents, 2);
case "amount_no_decimals":
// Ex. 1,135
return formatWithDelimiters(cents, 0);
case "amount_with_comma_separator":
// Ex. 1.134,65
return formatWithDelimiters(cents, 2, ".", ",");
case "amount_no_decimals_with_comma_separator":
// Ex. 1.135
return formatWithDelimiters(cents, 0, ".", ",");
case "amount_with_apostrophe_separator":
// Ex. 1'134.65
return formatWithDelimiters(cents, 2, "'", ".");
case "amount_no_decimals_with_space_separator":
// Ex. 1 135
return formatWithDelimiters(cents, 0, " ");
case "amount_with_space_separator":
// 1 134,65
return formatWithDelimiters(cents, 2, " ", ",");
case "amount_with_period_and_space_separator":
// 1 134.65
return formatWithDelimiters(cents, 2, " ", ".");
default:
return match;
}
});
}
Hi, this function isn't passed in this case:
When using the formatting option amount_no_decimals, the thousands separator (used for digit grouping) is determined from the international set standard for the currency code.
https://help.shopify.com/en/manual/international/pricing/currency-formatting
Hi , I am using
`
var Shopify = Shopify || {};
Shopify.money_format = "{{ shop.money_format }}";
Shopify.formatMoney = function(cents, format) {
if (typeof cents == 'string') {
cents = cents.replace('.', '');
}
var value = '';
var placeholderRegex = /{{\s*(\w+)\s*}}/;
var formatString = (format || this.money_format);
};`
I am getting an error
Uncaught (in promise) TypeError: Cannot read properties of null (reading '1')
The error is only raised at the first time i.e when someone clicks on a particular product , but error disappears when the same page is refreshed.
Would love some help here.