How to change language automatically using user browser language Yii2? - yii2

A user can change the language manually from the website. But for better user experience, I would like to change it automatically based on the users' browser language. I have a global Controller and can use init() and then redirect.
Please give me tips to do it right.

You should remember the chosen language for a user, if they had selected one previously, I store this in the database, in a user_preference table.
Then you need to intercept the request, it can be done in the application configuration file, using the on beforeRequest property.
If you don't have stored a preference for the current user, or the user is a guest, use the browser language to set the application language.
Configuration file
use app\models\User;
...
'on beforeRequest' => function ($event) {
$user_lang = '';
if (!Yii::$app->user->isGuest) {
// Check if you have stored a language preference for the user
$user_lang = User::findIdentity(Yii::$app->user->id)->getUserPreference('lang');
}
if (!empty($user_lang)) {
// If you have a stored preference for the user, use it
Yii::$app->language = $user_lang;
} else {
// If you don't have a preference, use the browser language
// Get the browser language from the headers
$browser_lang = Yii::$app->request->headers->get('accept-language');
// Alternatively get the headers from the event
// $event->sender->request->headers->get('accept-language')
// Calculate the language you want to provide based on the browser language
$language_code = LanguageHelper::calculatei18nCode($browser_lang);
Yii::$app->language = $language_code;
}
},
...
If you wanted to keep your configuration file clean, you could use filters instead to intercept the request.
Your LanguageHelper::calculatei18nCode($browser_lang) method would try to find a match for the browser language in the available languages, if it didn't find one it could return the closest match, or the default application language.
LanguageHelper
public static function calculatei18nCode ($browser_lang) {
// For example, if you are offering one translation file for french
if (stripos($browser_lang, 'fr')) {
return 'fr';
}
...
return 'en';
}

Related

Is it possible to inspect the values entered in the Adyen payment widget and run validations against those values? And give error states?

I'm looking to set my own validations on my Adyen payment module. Specifically I want to eliminate people's ability to insert incorrect characters in card holder name field (like emojis, etc).
You are able to customize the validation logic implementing one of the handlers
onChange: (state, component) => {
// triggered at every change
console.error("onChange " + JSON.stringify(state.data));
},
onSubmit: (state, component) => {
// triggered upon submit
console.error("onSubmit " + JSON.stringify(state.data));
// grab holderName
var holderName = state.data.paymentMethod.holderName;
// apply your validation...
if(validationOk) {
makePayment(state.data)
// etc etc
}
}
Check Web Dropin integration guide. Make sure to check which version you are using (to refer to the relevant documentation), however the workflow is similar.

Wikimedia function to get all my Templates

I need to get all the pages I have created like Templates in my wikimedia webpage. I have to do this with javascript.
Is this possible?
You can do this with a UserContribs API query, like this:
https://en.wikipedia.org/w/api.php?format=jsonfm&action=query&list=usercontribs&ucuser=Ilmari_Karonen&ucnamespace=10&ucshow=new&continue=
Basically, the parameters you need are:
format=json to get results in JSON format, which is probably what you want for JavaScript. (I've used jsonfm in the example link above to get pretty-printed human readable output.)
action=query to indicate that this is, indeed, a query rather than, say, an edit or a login attempt.
list=usercontribs to indicate that you want a list of a user's contributions (i.e. the stuff you see on the Special:Contributions page).
ucuser=your_username to select which user's contributions you want to see. (The example link above shows mine.)
ucnamespace=10 to select only contributions to templates. (10 is the namespace number for the built-in Template namespace).
ucshow=new to select only contributions that involve creating a new page. (Note that this also includes page moves; I don't see any simple way to filter those out.)
Of course, there are other parameters you may also want to include.
I've also included an empty continue= parameter to indicate that I want to use the new query continuation syntax, and to suppress the warning about it. Obviously, if you actually want to use query continuation, you'll need to implement the client-side part yourself (or use an MW API client that implements it for you). Here's one simplistic way to do that:
function getNewTemplatesForUser( username ) {
var queryURL = 'https://en.wikipedia.org/w/api.php?format=json&action=query&list=usercontribs&ucnamespace=10&ucshow=new';
queryURL += '&ucuser=' + encodeURIComponent( username );
var callback = function( json ) {
// TODO: actually process the results here
if ( json.continue ) {
var continueURL = queryURL;
for ( var attr in json.continue ) {
continueURL += '&' + attr + '=' + encodeURIComponent( json.continue[attr] );
}
doAjaxRequest( continueURL, callback );
}
};
doAjaxRequest( queryURL + '&continue=', callback );
}

Wiki - table content from an external source

Is it possible to have a wiki page with two tables reflecting the data from two different 3rd party sites?
If so, how to get it done? Will page templates be of any help here?
Short answer is no, there's no easy, built-in way to pull external content into a MediaWiki site. Allowing a third party to inject arbitrary content would be massive security risk.
Long answer is that anything is possible with extensions, either existing ones or ones you write yourself. The MediaWiki site has an entire category of listings for "Remote content extensions" that do this kind of thing in one form or another, with External Data looking particularly useful. You will need admin rights to install any of these, and you'll need to trust both the extension code and the data you pull in.
I already wrote exactly what you describe. Might be helpful for you.
# Define a setup function
$wgHooks['ParserFirstCallInit'][] = 'efStackOverflow_Setup';
# Add a hook to initialise the magic word
$wgHooks['LanguageGetMagic'][] = 'efStackOverflow_Magic';
function efStackOverflow_Setup( &$parser ) {
# Set a function hook associating the "example" magic word with our function
$parser->setFunctionHook( 'stag', 'efStackOverflow_Render' );
return true;
}
function efStackOverflow_Magic( &$magicWords, $langCode ) {
# Add the magic word
# The first array element is whether to be case sensitive, in this case (0) it is not case sensitive, 1 would be sensitive
# All remaining elements are synonyms for our parser function
$magicWords['stag'] = array(1, 'stag');
# unless we return true, other parser functions extensions won't get loaded.
return true;
}
function efStackOverflow_Render( $parser, $param1 = '', $param2 = '' ) {
// there was filtering
$modif = 0;
$cache_file_path = "cache/".$param1."_".$param2;
if (file_exists($cache_file_path))
$modif = time() - #filemtime ($cache_file_path);
if (file_exists($cache_file_path) and $modif < 60*60*24) {
return file_get_contents($cache_file_path);
}
$page = file_get_contents("http://www.google.com/rss/".$param1);
$xml = new SimpleXMLElement($page);
foreach ($xml as $key => $value) {
// do some
}
if (!empty($output))
file_put_contents($cache_file_path, $output);
return $output;
}
Mediawiki version was 1.16.

WinJS variable/object scope, settings, and events?

I am not sure what the proper heading / title for this question should be. I am new to WinJS and am coming from a .NET webform and winclient background.
Here is my scenario. I have a navigation WinJS application. My structure is:
default.html
(navigation controller)
(settings flyout)
pages/Home.html
pages/Page2.html
So at the top of the default.js file, it sets the following variables:
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
It seems like I cannot use these variables anywhere inside my settings flyout or any of my pages:ready functions. They are only scoped to the default.js?
In the same regard, are there resources on the interwebs (links) that show how to properly share variables, events, and data between each of my "pages"?
The scenario that I immediately need to overcome is settings. In my settings flyout, I read and allow the user to optionally set the following application setting:
var applicationData = Windows.Storage.ApplicationData.current;
var localSettings = applicationData.localSettings;
localSettings.values["appLocation"] = {string set by the user};
I want to respond to that event in either my default.js file or even one of my navigation pages but I don't know where to "listen". My gut is to listen for the afterhide event but how do I scope that back to the page where I want to listen from?
Bryan. codefoster here. If you move the lines you mentioned...
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
...up and out of the immediate function, they'll be in global scope and you'll have access to them everywhere. That's one of the first things I do in my apps. You'll hear warnings about using global scope, but what people are trying to avoid is the pattern of dropping everything in global scope. As long as you control what you put in there, you're fine.
So put them before the beginning of the immediate function on default.js...
//stuff here is scoped globally
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var nav = WinJS.Navigation;
(function () {
//stuff here is scoped to this file only
})();
If you are saving some data and only need it in memory, you can just hang it off the app variable instead of saving it into local storage. That will make it available to the whole app.
//on Page2.js
app.myCustomVariable = "some value";
//on Page3.js
if(app.myCustomVariable == "some value") ...
Regarding your immediate need:
like mentioned in the other answer, you can use datachanged event.
Regards sharing variables:
If there are variables that you would like to keep global to the application, they can be placed outside the anonymous function like mentioned in the Jeremy answer. Typically, that is done in default.js. Need to ensure that scripts using the global variables are placed after the script defining the global variable - in default.html. Typically - such variable will point to singleton class. For example: I use it in one of my apps to store authclient/serviceclient for the backend service for the app. That way - the view models of the multiple pages need not create instance of the object or reference it under WinJS namespace.
WinJS has also concept of Namespace which lets you organize your functions and classes. Example:
WinJS.Namespace.define('Utils.Http',
{
stringifyParameters: function stringifyParameters(parameters)
{
var result = '';
for (var parameterName in parameters)
{
result += encodeURIComponent(parameterName) + '=' + encodeURIComponent(parameters[parameterName]) + '&';
}
if (result.length > 0)
{
result = result.substr(0, result.length - 1);
}
return result;
},
}
When navigating to a page using WinJS.Navigation.navigate, second argument initialState is available as options parameter to the ready event handler for the page. This would be recommended way to pass arguments to the page unless this it is application data or session state. Application data/session state needs to be handled separately and needs a separate discussion on its own. Application navigation history is persisted by the winjs library; it ensures that if the app is launched again after suspension - options will be passed again to the page when navigated. It is good to keep the properties in options object as simple primitive types.
Regards events:
Typically, apps consume events from winjs library. That can be done by registering the event handler using addEventListener or setting event properties like onclick etc. on the element. Event handlers are typically registered in the ready event handler for the page.
If you are writing your own custom control or sometimes in your view model, you may have to expose custom events. Winjs.UI.DOMEventMixin, WinJS.Utilities.createEventProperties can be mixed with your class using WinJS.Class.mix. Example:
WinJS.Class.mix(MyViewModel,
WinJS.Utilities.createEventProperties('customEvent'),
WinJS.UI.DOMEventMixin);
Most often used is binding to make your view model - observable. Refer the respective samples and api documentation for details. Example:
WinJS.Class.mix(MyViewModel,
WinJS.Binding.mixin,
WinJS.Binding.expandProperties({ items: '' }));
Here is what I ended up doing which is kinda of a combination of all the answers given:
Created a ViewModel.Settings.js file:
(function () {
"use strict";
WinJS.Namespace.define("ViewModel", {
Setting: WinJS.Binding.as({
Name: '',
Value: ''
}),
SettingsList: new WinJS.Binding.List(),
});
})();
Added that file to my default.html (navigation container page)
<script src="/js/VMs/ViewModel.Settings.js"></script>
Add the following to set the defaults and start 'listening' for changes
//add some fake settings (defaults on app load)
ViewModel.SettingsList.push({
Name: "favorite-color",
Value: "red"
});
// listen for events
var vm = ViewModel.SettingsList;
vm.oniteminserted = function (e) {
console.log("item added");
}
vm.onitemmutated = function (e) {
console.log("item mutated");
}
vm.onitemchanged = function (e) {
console.log("item changed");
}
vm.onitemremoved = function (e) {
console.log("item removed");
}
Then, within my application (pages) or my settings page, I can cause the settings events to be fired:
// thie fires the oniteminserted
ViewModel.SettingsList.push({
Name: "favorite-sport",
Value: "Baseball"
});
// this fires the itemmutated event
ViewModel.SettingsList.getAt(0).Value = "yellow";
ViewModel.SettingsList.notifyMutated(0);
// this fires the itemchanged event
ViewModel.SettingsList.setAt(0, {
Name: "favorite-color",
Value: "blue"
});
// this fires the itemremoved event
ViewModel.SettingsList.pop(); // removes the last item
When you change data that needs to be updated in real time, call applicationData.signalDataChanged(). Then in the places that care about getting change notifications, listen to the datachanged on the applicationData object. This is also the event that is raised when roaming settings are synchronized between computers.
I've found that many times, an instant notification (raised event) is unnecessary, though. I just query the setting again when the value is needed (in ready for example).

With a browser, how do I know which decimal separator does the operating system use?

I'm developing a web application.
I need to display some decimal data correctly so that it can be copied and pasted into a certain GUI application that is not under my control.
The GUI application is locale sensitive and it accepts only the correct decimal separator which is set in the system.
I can guess the decimal separator from Accept-Language and the guess will be correct in 95% cases, but sometimes it fails.
Is there any way to do it on server side (preferably, so that I can collect statistics), or on client side?
Update:
The whole point of the task is doing it automatically.
In fact, this webapp is a kind of online interface to a legacy GUI which helps to fill the forms correctly.
The kind of users that use it mostly have no idea on what a decimal separator is.
The Accept-Language solution is implemented and works, but I'd like to improve it.
Update2:
I need to retrive a very specific setting: decimal separator set in Control Panel / Regional and Language Options / Regional Options / Customize.
I deal with four kinds of operating systems:
Russian Windows with a comma as a DS (80%).
English Windows with a period as a DS (15%).
Russian Windows with a period as a DS to make poorly written English applications work (4%).
English Windows with a comma as a DS to make poorly written Russian applications work (1%).
All 100% of clients are in Russia and the legacy application deals with Russian goverment-issued forms, so asking for a country will yield 100% of Russian Federation, and GeoIP will yield 80% of Russian Federation and 20% of other (incorrect) answers.
Here is a simple JavaScript function that will return this information. Tested in Firefox, IE6, and IE7. I had to close and restart my browser in between every change to the setting under Control Panel / Regional and Language Options / Regional Options / Customize. However, it picked up not only the comma and period, but also oddball custom things, like the letter "a".
function whatDecimalSeparator() {
var n = 1.1;
n = n.toLocaleString().substring(1, 2);
return n;
}
function whatDecimalSeparator() {
var n = 1.1;
n = n.toLocaleString().substring(1, 2);
return n;
}
console.log('You use "' + whatDecimalSeparator() + '" as Decimal seprator');
Does this help?
Retrieving separators for the current or a given locale is possible using Intl.NumberFormat#formatToParts.
function getDecimalSeparator(locale) {
const numberWithDecimalSeparator = 1.1;
return Intl.NumberFormat(locale)
.formatToParts(numberWithDecimalSeparator)
.find(part => part.type === 'decimal')
.value;
}
It only works for browsers supporting the Intl API. Otherwise it requires an Intl polyfill
Examples:
> getDecimalSeparator()
"."
> getDecimalSeparator('fr-FR')
","
Bonus:
We could extend it to retrieve either the decimal or group separator of a given locale:
function getSeparator(locale, separatorType) {
const numberWithGroupAndDecimalSeparator = 1000.1;
return Intl.NumberFormat(locale)
.formatToParts(numberWithGroupAndDecimalSeparator)
.find(part => part.type === separatorType)
.value;
}
Examples:
> getSeparator('en-US', 'decimal')
"."
> getSeparator('en-US', 'group')
","
> getSeparator('fr-FR', 'decimal')
","
> getSeparator('fr-FR', 'group')
" "
Ask the user, do not guess. Have a setting for it in your web application.
Edited to add:
I think it is ok to guess the default setting that works ok, say, 95% of the time. What I meant was that the user should still be able to override whatever guesses the software made. I've been frustrated too many times already when a software tries to be too smart and does not allow to be corrected.
Why not
console.log(0.1.toLocaleString().replace(/\d/g, ''));
function getDecimalSeparator() {
//fallback
var decSep = ".";
try {
// this works in FF, Chrome, IE, Safari and Opera
var sep = parseFloat(3/2).toLocaleString().substring(1,2);
if (sep === '.' || sep === ',') {
decSep = sep;
}
} catch(e){}
return decSep;
}
I can guess the decimal separator from
Accept-Language and the guess will be
correct in 95% cases, but sometimes it
fails.
This is IMO the best course of action. In order to handle the failures, add a link to set it manually next to the display area.
Using other people answers I compiled the following decimal and thousand separators utility functions:
var decimalSeparator = function() {
return (1.1).toLocaleString().substring(1, 2);
};
var thousandSeparator = function() {
return (1000).toLocaleString().substring(1, 2);
};
Enjoy!
Similar to other answers, but compressed as a constant:
const decimal=.1.toLocaleString().substr(1,1); //returns "." in Canada
Also, to get the thousands separator:
const thousands=1234..toLocaleString().substr(1,1); //returns "," in Canada
Just place the code at the top of your JS and then call as required to return the symbol.
For example (where I live), to remove commas from "1,234,567":
console.log( "1,234,567".replaceAll(thousands,"") ); //prints "1234567" to console.
I think you have to rely on JavaScript to give you the locale settings.
But apparently JS doesn't have direct access to this information.
I see Dojo Toolkit relies on an external database to find the locale information, although it might not take in account setting changes, for example.
Another workaround I see is to have a small silent Java applet that query this information from the system, and JavaScript to get it out of Java.
I can give more information if you don't know how to do it (if you want to go this convoluted route, of course).
[EDIT]
So I updated my knowledge of localization support in Java...
Unlike what I thought originally, you won't have directly the decimal separator or thousand separator characters directly, like you would do with line separator or path separator: instead Java offers APIs to format the numbers or dates you provide.
Somehow, it makes sense: in Europe you often put the currency symbol after the number, some countries (India?) have a more complex rule to separate digits, etc.
Another thing: Java correctly finds the current locale from the system, but doesn't take information from there (perhaps for above reasons). Instead it uses its own set of rules. So if you have a Spanish locale where you replaced decimal separator with an exclamation sign, Java won't use it (but perhaps neither your application, anyway...).
So I am writing an applet exposing a service (functions) to JavaScript, allowing to format numbers to the current locale. You can use it as such, using JavaScript to format numbers on the browser. Or you can just feed it with some sample number and extract the symbols from there, using them locally or feeding them back to the server.
I finish and test my applet and post it there soon.
OK, I have something to show, more a proof of concept than a finished product, but because of lack of precise specifications, I leave it this way (or I will over-engineer it). I post in a separate message because it will be a bit long.
I took the opportunity to try a bit more jQuery...
The Java code:
GetLocaleInfo.java
import java.applet.*;
import java.util.Locale;
import java.text.*;
public class GetLocaleInfo extends Applet
{
Locale loc;
NumberFormat nf;
NumberFormat cnf;
NumberFormat pnf;
// For running as plain application
public static void main(String args[])
{
final Applet applet = new GetLocaleInfo();
applet.init();
applet.start();
}
public void init() // Applet is loaded
{
// Use current locale
loc = Locale.getDefault();
nf = NumberFormat.getInstance();
cnf = NumberFormat.getCurrencyInstance();
pnf = NumberFormat.getPercentInstance();
}
public void start() // Applet should start
{
// Following output goes to Java console
System.out.println(GetLocaleInformation());
System.out.println(nf.format(0.1));
System.out.println(cnf.format(1.0));
System.out.println(pnf.format(0.01));
}
public String GetLocaleInformation()
{
return String.format("Locale for %s: country=%s (%s / %s), lang=%s (%s / %s), variant=%s (%s)",
loc.getDisplayName(),
loc.getDisplayCountry(),
loc.getCountry(),
loc.getISO3Country(),
loc.getDisplayLanguage(),
loc.getLanguage(),
loc.getISO3Language(),
loc.getDisplayVariant(),
loc.getVariant()
);
}
public String FormatNumber(String number)
{
double value = 0;
try
{
value = Double.parseDouble(number);
}
catch (NumberFormatException nfe)
{
return "!";
}
return nf.format(value);
}
public String FormatCurrency(String number)
{
double value = 0;
try
{
value = Double.parseDouble(number);
}
catch (NumberFormatException nfe)
{
return "!";
}
return cnf.format(value);
}
public String FormatPercent(String number)
{
double value = 0;
try
{
value = Double.parseDouble(number);
}
catch (NumberFormatException nfe)
{
return "!";
}
return pnf.format(value);
}
}
An example of HTML page using the above applet:
GetLocaleInfo.html
<!-- Header skipped for brevity -->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.js"></script>
<script type="text/javascript">
var applet;
$(document).ready(function()
{
applet = document.getElementById('LocaleInfo');
$('#Results').text(applet.GetLocaleInformation());
});
</script>
<script type="text/javascript">
function DoFormatting()
{
$('table.toFormat').each(function()
{
var table = $(this);
$('td', table).each(function(cellId)
{
var val = $(this);
if (val.is('.number'))
{
val.text(applet.FormatNumber(val.text()));
}
else if (val.is('.currency'))
{
val.text(applet.FormatCurrency(val.text()));
}
else if (val.is('.percent'))
{
val.text(applet.FormatPercent(val.text()));
}
});
});
}
</script>
</head>
<body>
<div id="Container">
<p>Page to demonstrate how JavaScript can get locale information from Java</p>
<div id="AppletContainer">
<object classid="java:GetLocaleInfo.class"
type="application/x-java-applet" codetype="application/java"
name="LocaleInfo" id="LocaleInfo" width="0" height="0">
<param name="code" value="GetLocaleInfo"/>
<param name="mayscript" value="true"/>
<param name="scriptable" value="true"/>
<p><!-- Displayed if object isn't supported -->
<strong>This browser does not have Java enabled.</strong>
<br>
<a href="http://java.sun.com/products/plugin/downloads/index.html" title="Download Java plug-in">
Get the latest Java plug-in here
</a> (or enable Java support).
</p>
</object>
</div><!-- AppletContainer -->
<p>
Click on the button to format the table content to the locale rules of the user.
</p>
<input type="button" name="DoFormatting" id="DoFormatting" value="Format the table" onclick="javascript:DoFormatting()"/>
<div id="Results">
</div><!-- Results -->
<table class="toFormat">
<caption>Synthetic View</caption>
<thead><tr>
<th>Name</th><th>Value</th><th>Cost</th><th>Discount</th>
</tr></thead>
<tbody>
<tr><td>Foo</td><td class="number">3.1415926</td><td class="currency">21.36</td><td class="percent">0.196</td></tr>
<tr><td>Bar</td><td class="number">159263.14</td><td class="currency">33</td><td class="percent">0.33</td></tr>
<tr><td>Baz</td><td class="number">15926</td><td class="currency">12.99</td><td class="percent">0.05</td></tr>
<tr><td>Doh</td><td class="number">0.01415926</td><td class="currency">5.1</td><td class="percent">0.1</td></tr>
</tbody>
</table>
</div><!-- Container -->
</body>
</html>
Tested on Firefox 3.0, IE 6, Safari 3.1 and Opera 9.50, on Windows XP Pro SP3.
It works without problem with the first two, on Safari I have a strange error after init() call:
java.net.MalformedURLException: no protocol:
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at java.net.URL.<init>(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation.checkLiveConnectCaller(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation.access$000(Unknown Source)
at sun.plugin.liveconnect.SecureInvocation$2.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at sun.plugin.liveconnect.SecureInvocation.CallMethod(Unknown Source)
but it still works.
I can't get it work with Opera: the applet loads correctly, as I can see the trace of init() call in the Java console, I have no errors when JavaScript calls the Java functions (except if I add and call a method getting a JSObject parameter, curiously), but the Java functions are not called (I added trace of the calls).
I believe Liveconnect works in Opera, but I don't see yet how. I will research a bit more.
[Update] I removed references to non-existing jar file (which doesn't stop other browsers) and I got a trace of the calls, but it doesn't update the page.
Mmm, if I do alert(applet.GetLocaleInformation()); I got the information, so it might be a jQuery issue.
Even if you knew what locale this "GUI Application" is running under, you still have to figure out how it is getting the current locale, and how it is determining the decimal separator.
i don't know how it is done on a Mac, but on Windows applications are supposed to interrogte the user's preferences set via the Control Panel. It's quite possible this mystery applicaiton is ignoring those settings, and using their own internal setup instead.
Or perhaps they're taking the current locale, and inferring the rest, rather than being told.
Even then, in english, numbers are given in groups of 3 digits, with a comma separating the groups. i.e.:
5,197,359,078
Unless the number was an integer that contains a phone number:
519-735-9078
Unless of course the number was an integer that contains an account number:
5197359078
In which case, you're back to hard-coded overridden logic.
Edit: Removed currency example, since currency has its own formatting rules.
"Is there any way to do it on server
side (preferably, so that I can
collect statistics), or on client
side?"
No you can't. That GUI is looking at some user or machine specific settings.
First, you probably do not know at what settings this UI is looking.
Second, with a webapplication you will probably not be able to check these settings (clientside --> Javacsript).
Is there any way to do it on server side (preferably, so that I can collect statistics), or on client side?
from Server side. That could get decimal separator from system by (.NET)
string x = CultureInfo.CurrentCulture.NumberFormat.NumberDsecimalSeparator;
The rest of work is check delimiter for exporting which is different from x
comma (",") or semicolon (";") in case csv export
Another possible solution: You could use something like GeoIP (example in PHP) to determine the user's location and decide based on these information.