Skip to content

Instantly share code, notes, and snippets.

@stewartknapman
Created February 27, 2017 23:25
Show Gist options
  • Save stewartknapman/8d8733ea58d2314c373e94114472d44c to your computer and use it in GitHub Desktop.
Save stewartknapman/8d8733ea58d2314c373e94114472d44c to your computer and use it in GitHub Desktop.
The Shopify.formatMoney method extracted from option_selection.js for stand-alone purposes.
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);
};
@thosakwe
Copy link

thosakwe commented Aug 3, 2024

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;
    }
  });
}

@thangpqgm
Copy link

thangpqgm commented Aug 20, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment