Campaign Ordering/Editing Posting Requirements Changes
Campaign Ordering/Editing Posting Requirements Changes
We have received feedback from ATSs regarding currency input validations in posting requirements form for contracts.
For some posting requirements, HAPI Backend has float rule and the HAPI Backend Job Post Implementation Guide suggests this type of validation for such fields should be: float - numbers with optional comma (,) as a thousand separator and optional period (.) as a decimal point however HAPI Elements was preventing the comma from being entered. Some examples for this case are Minimum salary (not displayed on ad) and Maximum salary (not displayed on ad) fields for Seek Australia.
With changes introduced in version 3.1, user can now enter commas. Because there are numerous ways a user can enter commas, depending on their locale, HAPI Elements converts the output to a plain decimal with a dot and two fraction digits and no thousands separator, for example 1270.00. A grouping comma is rejected by some job boards. The float rule still treats a comma in the typed value as optional. We do this conversion via an overlay 1.5 second(s) after user stopped typing via a timeout. Clicking the overlay replaces the typed value with the plain decimal, so 1270 becomes 1270.00.
The overlay looks like:

We also fix mistakes that a user can make. List of valid inputs (already a plain decimal with two fraction digits):
1.0010.5012.70100.001270.001270.501000.0010000.25100000.001000000.0010000000.00100000000.001000000000.005000000000.50
List of invalid inputs that are corrected to a plain decimal:
1270→1270.001270.5→1270.501270,50→1270.501,00→1.001,5→1.501.270→1270.00(dot is a thousands separator)1.270,00→1270.001.000.000→1000000.001.000.000,50→1000000.501,270→1270.001,270.00→1270.001,000,00→1000.00100,000,000,000,00→100000000000.0010,000.25→10000.2510,000.000→10000.001,000,000.000→1000000.005,000,000,000.50→5000000000.50
Here is how the function works. A group of exactly three digits is a thousands separator. One or two digits after the last mark are the fractional part. When both a dot and a comma appear, the rightmost mark is the decimal separator. The result is formatted with toFixed(2), which never inserts a grouping character.
const GROUPED_WITH_DOTS = /^\d{1,3}(\.\d{3})+$/
const GROUPED_WITH_COMMAS = /^\d{1,3}(,\d{3})+$/
const parseLocalizedFloat = (raw: string): number | null => {
const trimmed = raw.trim()
if (!/^\d+([.,]\d+)*$/.test(trimmed)) {
return null
}
const lastComma = trimmed.lastIndexOf(",")
const lastDot = trimmed.lastIndexOf(".")
let canonical: string
if (lastComma === -1 && lastDot === -1) {
canonical = trimmed
} else if (lastComma === -1) {
canonical = GROUPED_WITH_DOTS.test(trimmed)
? trimmed.replace(/\./g, "")
: trimmed
} else if (lastDot === -1) {
if (GROUPED_WITH_COMMAS.test(trimmed)) {
canonical = trimmed.replace(/,/g, "")
} else {
const head = trimmed.slice(0, lastComma).replace(/,/g, "")
const tail = trimmed.slice(lastComma + 1)
canonical = `${head}.${tail}`
}
} else if (lastComma > lastDot) {
const head = trimmed.slice(0, lastComma).replace(/[.,]/g, "")
const tail = trimmed.slice(lastComma + 1)
canonical = `${head}.${tail}`
} else {
const head = trimmed.slice(0, lastDot).replace(/[.,]/g, "")
const tail = trimmed.slice(lastDot + 1)
canonical = `${head}.${tail}`
}
if (!/^\d+(\.\d+)?$/.test(canonical)) {
return null
}
const parsed = Number(canonical)
if (!Number.isFinite(parsed)) {
return null
}
return parsed
}
export const convertStringifiedNumberToFloat = (
num: string | undefined,
isRequired: boolean,
) => {
const defaultFloat = isRequired ? "0.00" : ""
if (!num || num.trim() === "") {
return defaultFloat
}
const parsed = parseLocalizedFloat(num)
if (parsed === null) {
return defaultFloat
}
return parsed.toFixed(2)
}As part of this change, the following translations were added:
| Key | "en" value | "de" value | "nl" value | "fr" value |
|---|---|---|---|---|
| common.field-should-be-float | This field can only contain numbers, dots and commas. | Dieses Feld darf nur Zahlen, Punkte und Kommas enthalten. | Dit veld kan alleen cijfers, punten en komma's bevatten. | Ce champ ne peut contenir que des chiffres, des points et des virgules. |
| common.autocorrection-must-be-applied | Following auto-correction must be applied, click to apply | Folgende Autokorrektur muss angewendet werden, klicken Sie zum Anwenden | De volgende automatische correctie moet worden toegepast, klik om toe te passen | La correction automatique suivante doit être appliquée, cliquez pour appliquer |
| common.diff-added-removed | Red indicates removed values, green indicates added values | Rot zeigt entfernte Werte, Grün zeigt hinzugefügte Werte | Rood geeft verwijderde waarden aan, groen geeft toegevoegde waarden aan | Le rouge indique les valeurs supprimées, le vert indique les valeurs ajoutées |