Skip to content

Commit

Permalink
Add localised number formatting for 'count'
Browse files Browse the repository at this point in the history
Adds Intl.NumberFormat detection, using it for `count` values if supported by the browser. Addresses #2568.
  • Loading branch information
querkmachine committed Jun 13, 2022
1 parent 4b0b7fd commit 4527657
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/govuk/components/character-count/character-count.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,14 @@ examples:
threshold: 75
label:
text: Full address

- name: with very high character limit
data:
id: with-very-high-limit
name: with-very-high-limit
maxlength: 1280
label:
text: Life story

- name: with localised fallback text
description: Fallback counter text (shown if JavaScript is not available) translated into Welsh
Expand Down
31 changes: 27 additions & 4 deletions src/govuk/i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,16 @@ I18n.prototype.t = function (lookupKey, options) {
*/
I18n.prototype.replacePlaceholders = function (phrase, placeholderMap) {
for (var key in placeholderMap) {
phrase = phrase.replace(new RegExp(this.separators[0] + key + this.separators[1], 'g'), placeholderMap[key])
var value = placeholderMap[key]

// If the key is `count`, subject the value to number formatting
// This is limiting, just so we don't accidentally format things like phone numbers
if (this.hasIntlNumberFormatSupport() && key === 'count') {
value = Intl.NumberFormat(this.locale).format(value)
}

// Perform the replacement
phrase = phrase.replace(new RegExp(this.separators[0] + key + this.separators[1], 'g'), value)
}
return phrase
}
Expand Down Expand Up @@ -184,7 +193,7 @@ I18n.prototype.getPluralSuffix = function (count) {
// Check to verify that all the requirements for Intl.PluralRules are met.
// If so, we can use that instead of our custom implementation. Otherwise,
// use the hardcoded fallback.
if (this.hasIntlSupport()) {
if (this.hasIntlPluralRulesSupport()) {
var pluralRules = new Intl.PluralRules(this.locale)
keySuffix = pluralRules.select(count)
} else {
Expand All @@ -209,7 +218,7 @@ I18n.prototype.getPluralSuffix = function (count) {
}

/**
* Check to see if the browser supports Intl and the parts of it we want to use.
* Check to see if the browser supports Intl and Intl.PluralRules.
*
* It requires all conditions to be met in order to be supported:
* - The browser supports the Intl class (true in IE11)
Expand All @@ -218,10 +227,24 @@ I18n.prototype.getPluralSuffix = function (count) {
*
* @returns {boolean} - Returns true if all conditions are met. Returns false otherwise.
*/
I18n.prototype.hasIntlSupport = function () {
I18n.prototype.hasIntlPluralRulesSupport = function () {
return Boolean(window.Intl && ('PluralRules' in window.Intl && Intl.PluralRules.supportedLocalesOf(this.locale).length))
}

/**
* Check to see if the browser supports Intl and Intl.NumberFormat.
*
* It requires all conditions to be met in order to be supported:
* - The browser supports the Intl class (true in IE11)
* - The implementation of Intl supports NumberFormat (also true in IE11)
* - The browser/OS has number formatting rules for the current locale (browser dependent)
*
* @returns {boolean} - Returns true if all conditions are met. Returns false otherwise.
*/
I18n.prototype.hasIntlNumberFormatSupport = function () {
return Boolean(window.Intl && ('NumberFormat' in window.Intl && Intl.NumberFormat.supportedLocalesOf(this.locale).length))
}

/**
* Different pluralisation rule sets
*
Expand Down

0 comments on commit 4527657

Please sign in to comment.