Yes it is odd that the format strings are not interpreted in a locale sensitive way, i can only assume its due to the Java thread not being set to the users locale internally. There are two ways to approach this problem. Both approaches could be used directly in a controller with custom bindings or wrapped for reuse in a Visualforce Component, as per this idea, How to call parametrized function from Visualforce?.
Dynamically Generating your Format String
Ideally UserInfo would give us the decimal and thousand separators but it does not currently. However we can determine them indirectly. The Apex Decimal.format method is locale sensitive, the following code can be used to derive the separators needed.
public String getDynamicFormatString()
{
Decimal value = 1000.10;
String formattedValue = value.format();
String thousandSep = formattedValue.substring(1,2);
String decimalSep = formattedValue.substring(5,6);
return '{0,number,#'+thousandSep+'###'+thousandSep+'###'+thousandSep+'###'+thousandSep+'###'+thousandSep+'##0'+decimalSep+'00}';
}
You can then expose this as binding in your page or component to use with the
<apex:outputText value="{!DynamicFormatString}">
<apex:param value="{!ValueToFormat}" />
</apex:outputText>
Using outputField component with a dummy SObject Field
With this approach you have to use the outputField component instead of the outputText component. This requires a custom field binding though. So in this case you will have to create a custom object in your org / package who's sole purpose is to be used for formatting values, no data or user interaction.
For example if you are setting up your view state, construct the object and set its field/s with the values you wish to format, then bind to those fields, the following code fragments show the general idea.
public OutputHelper__c outputHelper {get;set;}
outputHelper = new OutputHelper__c(Number__c = valueToFormat);
<apex:outputField value="{!outputHelper.Number__c}"/>
The above sample can be scaled to support multiple fields to format by either wrapping it a Visualforce Component or adding more fields e.g. Number1__c. For a lighter version you can hijack a standard field, for example the AnnualRevenue field on the Account.
public Account outputHelper {get;set;}
outputHelper = new Account(AnnualRevenue = valueToFormat);
<apex:outputField value="{!outputHelper.AnnualRevenue}"/>
The doc may be contradictory as I use apex:inputField
with ACM all day, every day. From the VF standard component reference:
You can't associate this inputField with a formula merge field of type currency if your organization is using dated exchange rates.
This is saying you can't do this:
value="{!IF(foo__c,opportunity.amount,opportunity.next_best_amount__c)}"
but you can certainly do <apex:inputField value="{!opportunity.amount}"/>
as my VF pages do that (actually they do : <apex:inputField value="{!ow.o.amount}"/>
referring to a wrapper class around Opportunity but that shouldn't matter.
Now outputFields are a different story and here the VF doc is consistent with your ACM doc snippet:
You cannot associate this output field with a currency merge field if that field value is calculated using dated exchange rates.
I would go with a component and its own controller that could deal with the locale issues. Pass in the currency field to the component and let the component's controller format it for you.
Best Answer
if you use the following functions in SOQL queries, it will support localized result
SELECT statements can include the toLabel() and convertCurrency() functions in support of localized fields.
toLabel():
Use toLabel() on regular, multi-select, division, or currency code picklist fields (any field that has picklist values returned by the relevant describe call), data category group and data category unique name fields or RecordType names. Any organization can use toLabel(). It is particularly useful for organizations that have the Translation Workbench enabled. For example:
This query returns lead records with the record type name translated into the language for the user who issued the query.
convertCurrency():
If an organization is multicurrency enabled, you can use convertCurrency() in the SELECT clause to convert currency fields to the user's currency. Use this syntax for the SELECT clause: convertCurrency(field) For example:
If an organization has enabled advanced currency management, dated exchange rates will be used when converting currency fields on opportunities, opportunity line items, and opportunity history. For more information, check the SOQL documentation in salesforce