I'm working on a custom currency input field component and facing a challenging issue with decimal value conversion and rounding when values exceed 10,000 (5+ digits).
Here's my current implementation:
a!localVariables( a!textField( label: ri!label, labelPosition: a!defaultValue(ri!labelPosition, "ABOVE"), value: a!currency( isoCode: a!defaultValue(ri!isoCode, "BRL"), value: rule!process_BRLInputSanitizer( value: ri!value, toDecimal: true, showSeparators: false ), decimalPlaces: 2, showSeparators: true ), placeholder: ri!placeholder, saveInto: a!localVariables( { a!save( ri!value, a!currency( isoCode: a!defaultValue(ri!isoCode, "BRL"), value: rule!process_BRLInputSanitizer( value: save!value, toDecimal: true, showSeparators: false ), decimalPlaces: 2, showSeparators: true ), ), ri!saveInto } ), disabled: a!defaultValue(ri!disabled, false), readOnly: a!defaultValue(ri!readOnly, false), refreshAfter: "KEYPRESS", validations: { ri!validations }, showWhen: a!defaultValue(ri!showWhen, true), instructions: ri!instructions, helpTooltip: ri!helpTooltip ) )
Supporting Rule (process_BRLInputSanitizer):
a!localVariables( local!toDecimal: a!defaultValue(ri!toDecimal, false), local!value: tostring(ri!value), local!left: substitute(local!value, ",", "."), local!right: substitute(local!value, ".", ","), local!result: if( local!toDecimal, concat( left(local!right, len(local!right) - 3), right(local!left, 3) ), concat( left(local!left, len(local!left) - 3), right(local!right, 3) ) ), if( a!defaultValue(ri!showSeparators, true), local!result, if( local!toDecimal, substitute(local!result, ",", ""), substitute(local!result, ".", "") ) ) )
Questions:
I'm essentially trying to create a currency input that displays proper formatting (R$323,845.27) while maintaining the underlying decimal value for record Type integration.
Any recommendations for existing solutions or insights into the rounding behavior would be greatly appreciated!
Thank you all for your time and assistance.
Discussion posts and replies are publicly visible
Appian's default way of displaying decimal numbers takes some sometimes unintuitive liberties with the number of significant figures shown - in ways that are a little unintuitive and opaque to not only the end user but also the designer (frustratingly). I'm not exactly sure I'm comprehending the manual conversions you're with your utuility rule, but I was under the impression that a!currency() was supposed to handle things like "dots instead of commas and commas instead of dots" automatically for currencies that use opposing systems (though i haven't tested this). BTW, are users not using locales that support the proper number entry system inherently? I thought it worked without manual conversion when the locale was set right (also haven't personally tested though).
My general advice at this point would be to go back to basics and make sure you're doing any manual conversion on a displayed number (versus the underlying decimal value) only at the very end, to avoid it becoming confused.
Yes, the currency formatter is meant to handle it, but it's automatically rounding the value when I convert it back to decimal, even though I don't want it to.
Could you provide a screenshot of an example of the output you're seeing and the actual underlying value that you'd expect to be seeing?
Have you tried formatting the output through functions like 'text(value, "0.00")' to signify that you want the displayed output to show the entire number including 2 decimal places at all times? Because as I said, when just displaying decimal data, Appian (badly) guesses at what level of significant digits should be displayed to the user.
I was just about to provide it
I will try what you suggested in just a sec
So basically my prior answer is correct:
a!localVariables( local!amount, local!amountDecimal, a!textField( label: "Amount in Text", /* Instructions show the saved datatype*/ instructions: "Type of local!amount: " & typename(typeof(local!amount)), value: a!currency( isoCode: "BRL", value: local!amount, format: "SYMBOL" ), /* Instead of saving the value as text, a!save() is used to store to the desired datatype*/ saveInto: { a!save( local!amountDecimal, text(todecimal(save!value), "#.##") ), a!save(local!amount, save!value) } ) )
Right, this method text() casts the value to text.
However, I am wondering as well if, whenever it casts, Appian is gonna pass the real value when it's expected to be a decimal, or, it is simply going to round, and miss the decimals digits.
For example: a recordType's field is a Decimal, so, when appian automatically converts the value to the decimal field in my grid `fv!item.field` (which expects a decimal but receives a casted value), is it gonna simply round or is it going to preserve the original value as sholud be (ex.: 400300.37 instead of 400300.4)?
Silas. B. Ferreira said:However, I am wondering as well if Appian is gonna pass the real value when it's expected to be a decimal
The "real value" is what's being stored in Appian, which is what I'm trying to show you. The rounded value you're seeing in the local variables panel is merely a "user facing" output, not the internal value.