Feature request for dcc.Input

Currently dcc.Input only supports numbers with a dot decimal separator.
Input | Dash for Python Documentation | Plotly
This is a request for the feature that dcc.Input numbers also be accepted which a comma as decimal separator.
About 1.3 billion of the world’s population use comma as the decimal separator.
It might be related to ‘locale’ but could also be implemented just in dcc.Input itself.
Many years ago I wrote a (Pacsal / Delphi) routine that converts a string to a float, which would also accept strange inputs (like both = both thousand separator and decimal separator) as well as 1E3 = 1000 and so on. Here it is, just for inspiration:

{
 REAL MATH ROUTINES

 Created by       : Claus Futtrup
 Date             : 3. April 1997 (24. August 1997 valid until 9/3-01)
 Last modified    : 12. June 2001
}

{DEFINE CHECK}                         { use various checking compiler-directives }
{DEFINE DEBUG}                         { use debugging compiler-directives }

  {* Compiler directives *}

{$I OPTIONS.INC}                        { include this file }

interface

const                                   { extended goes 3.4E-4932 to 1.1E4932}
  exp_max = 308;                        { double = float goes from 5.0E-324 to 1.7E308 }
  precision = 15;                       { and holds 15-16 digits }
  e = 2.71828182846;                    { the number e }

type
  float = double;

var
  zero, inf : float;                    { zero or infinity numbers }
  eps : float;                          { epsilon, a negligible small number }

function s2float(s : string; var flag : boolean) : float;   { given string, returns a float }
implementation

function s2float(s : string; var flag : boolean) : float;
var
  epos : byte;                          { position of E (or e), the exponential }
  errorcode : integer;
  the_number : float;                   { the converted number }
  str : string;                         { temporary/local string }
  i : byte;                             { counter }
  j : byte;                             { counter }

begin
    flag := true;
    the_number := 0;
    epos := 0;
    i := 0;
    j := 0;
    for errorcode := 1 to length(s) do  { use errorcode as counter }
      begin
        case s[errorcode] of            { look for ... }
          'E' : inc(epos);
          'e' : inc(epos);              { use epos as a counter }
          '.' : inc(i);
          ',' : inc(j);
        end;
      end;
    if (epos>1) OR ((i>1) AND (j>1)) then
      flag := false
    else                                { else number accepted, for now }
      begin
        if (epos=1) then                { i E found, then }
          begin
            epos := pos('e',s);         { examine number after E }
            if (epos=0) then
              epos := pos('E',s);
            str := copy(s,epos+1,length(s));
            if (pos(',',str)>0) OR (pos('.',str)>0) then
              flag := false
            else
              begin
                val(str,the_number,errorcode);
                if errorcode <> 0 then  { if conversion error }
                  flag := false
                else if the_number>=exp_max then
                  the_number := inf     { if very large, set to infinity }
                else
                  the_number := 0;      { else restore, exponential is accepted }
              end;
          end;
        if flag AND (the_number=0) then { if exponential OK or no exponential }
          begin
            if (i=1) then
              begin
                if (j=1) then
                  begin
                    i := pos('.',s);
                    j := pos(',',s);
                    if (i<j) then       { the first appearance is removed }
                      begin             { because the last is assumed }
                        delete(s,i,1);  { to be the decimal separator }
                        s[pos(',',s)] := '.'; { convert comma to dot }
                      end
                    else {j<i}
                      delete(s,j,1);
                  end
                else if (j>1) then      { remove all commas }
                  for i := 1 to j do
                    delete(s,pos(',',s),1);
              end
            else if j=1 then
              begin
                if i>1 then             { remove all dots }
                  for j := 1 to i do
                    delete(s,pos('.',s),1);
                s[pos(',',s)] := '.';   { convert comma to dot }
              end;
            val(s,the_number,errorcode);{ convert text string to number }
            if errorcode <> 0 then      { if conversion error(?) }
              flag := false;
          end;
      end;
  if (flag=false) then
    begin
      s2float := 0;                     { error in conversion }
    end
  else
    s2float := the_number;              { successful conversion or inf }
end;

With kind regards,
Claus

Hello @cfuttrup !

Just FYI you can check out Number Input from Dash Mantine Component. You can choose any decimal and thousand separator you want :slight_smile:

Hi Martin

Thank you for the tip. I was unaware of Mantine Components, which apparently is a 3rd party library. I confirm that on their test page I am able to enter numbers with either a dot or a comma … that’s a good indicator that this might work.

P.S. I still hope dcc.Input becomes smarter.

Best regards,
Claus