0

Here, you can see, how to realize two-way data-binding between parent and child component. The example works well for ints and there is also an answer for doubles. But there seems to be a problem with the culture info. Also, the behavior is different in different browsers. The following code works well for enet, who answered above linked question:

Index.razor

@page "/"
<Child @bind-Value="@Value" Min="0" Max="100" />
<div>@Value.ToString()</div>

@code
{
    private double Value { get; set; } = 10.1; // default value
}

Child.razor

<div>
    <input type="number" value="@Value"
       @onchange="@((args) => ValueChanged.InvokeAsync(Convert.ToDouble(args.Value)) )"
       min="@Min" max="@Max" step="0.01">
</div>

@code {
    [Parameter] public double Value { get; set; }
    [Parameter] public EventCallback<double> ValueChanged { get; set; }
    [Parameter] public double Max { get; set; }
    [Parameter] public double Min { get; set; }
}

However, it does not work for me, probably because of the CultureInfo, which is German in my case. Edge and Chrome show empty inputs on the GUI. Firefox shows "10,1" (with a comma as decimal separator). Clicking the upper spin button, changes the value to "10.11" (with a dot) for a second, what is then automatically set to "1011". The following images show the state before click, during click and after click:

Firefox: before click during click after click

Edge: before click during click after click

I changed

@onchange="@((args) => ValueChanged.InvokeAsync(Convert.ToDouble(args.Value)) )"

to

@onchange="@((args) => ValueChanged.InvokeAsync(Convert.ToDouble(args.Value, System.Globalization.CultureInfo.InvariantCulture)) )"

This does not change Edge's behavior but Firefox results in my expected value:

after click

Satisfied for the moment, I added the parameter [Parameter] public double Step { get; set; } and step="@Step" in Child.razor as well as Step="0.01" in Index.razor. I expected the same behavior but now after click it is:

after click

Questions:

  1. How can I make this code really culture-invariant?
  2. Why is there a different behavior with the parameter Step?

Edit

I have the prove now, that it is a CultureInfo issue. To reproduce, please do the following steps (tested with Edge):

  1. If not already, change Edge's language to English.
  2. Go to the BlazorFiddle, I created. You should see "10.1" in the input and also "10.1" in the div.
  3. Change Edge's language to German.
  4. Restart Edge and visit the Fiddle again. You should see an empty input and "10,1" in the div now.

This only happens, when I use the input in a child component, but not when it is used in the parent.

Flippowitsch
  • 315
  • 3
  • 15
  • Why exactly are you doing this? The InputNumber component already does this, and gets the CultureInfo stuff right. You can look up the source, you will have to control the formatting in both directions. You now have only 1 direction and as you can see that doesn't work well for round-tripping data. – H H Jan 25 '22 at 12:30
  • I do not want to do this. I added it, because I realized, that in Firefox before I click the upper spin button, there is a comma, during click there is a dot and after click, there is no decimal separator (but a way too large number). If you tell me, that the problem is not the `CultureInfo`, I am happy with that. But what else solves my problem? – Flippowitsch Jan 25 '22 at 12:41
  • You need to apply CultureInfo twice. You only have it once. – H H Jan 25 '22 at 12:59
  • Where must the second one be? – Flippowitsch Jan 25 '22 at 13:12
  • @HenkHolterman Why do you say that `InputNumber` "gets the CultureInfo stuff right"? It'll just use `` and leave the formatting and parsing to the browser. There's no `CurrentCulture` involved. Instead of having control over the presentation it is now up to the browser and their implementation of how they handle locale + region. – Bouke Jun 01 '22 at 16:02
  • @Flippowitsch the issue is with ``. When you specify `type=number`, you yield all control over formatting and parsing to the user agent (browser). If you want to handle this server-side, you should use `type=text` instead. – Bouke Jun 01 '22 at 18:52
  • @Bouke - look up the source. They keep a text shadow value and take control over formatting. – H H Jun 03 '22 at 08:12
  • @HenkHolterman can you point me to the relevant parts? I only see `CultureInfo.InvariantCulture` which is used for interop with JavaScript and ``. – Bouke Jun 04 '22 at 10:07

1 Answers1

0

The issue is with <input type=number />. When you specify type=number, you yield all control over formatting and parsing to the user agent (browser). If you want to have control over the how the number is shown to the user (formatting) and parsing, you should do this server-side and use type=text instead. Note that this is not related to Blazor, but just how type=number works. And mind you, this even differs per browsers and browser versions.

As a side-note, InputNumber uses CultureInvariant to interface with the input's internal value which is always formatted with a point.

Bouke
  • 11,768
  • 7
  • 68
  • 102
  • Thank you @Bouke. Currently, I do not implement the `input`s as children and this way, it works well. It is not the elegant way, because using components reduced code as well as maintenance effort and improved readability but for now, it is how it is. Maybe one day I will replace the `type=number` by `type=text` what would be nice, because of the different decimal separators in English and German. – Flippowitsch Jun 02 '22 at 05:48