Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NumberInput - CultureInfo updates #617

Merged
merged 4 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,41 +1,49 @@
<div class="mb-3">
<label class="form-label">Enter int number</label>
<NumberInput TValue="int" @bind-Value="@amount" />
<div class="mt-1">Entered Number: @amount</div>
</div>

<div class="mb-3">
<label class="form-label">Enter int? number</label>
<NumberInput TValue="int?" @bind-Value="@amount2" />
<div class="mt-1">Entered Number: @amount2</div>
</div>

<div class="mb-3">
<label class="form-label">Enter float number</label>
<NumberInput TValue="float" @bind-Value="@amount3" />
<div class="mt-1">Entered Number: @amount3</div>
</div>

<div class="mb-3">
<label class="form-label">Enter float? number</label>
<NumberInput TValue="float?" @bind-Value="@amount4" />
<div class="mt-1">Entered Number: @amount4</div>
</div>

<div class="mb-3">
<label class="form-label">Enter double number</label>
<NumberInput TValue="double" @bind-Value="@amount5" />
<div class="mt-1">Entered Number: @amount5</div>
</div>

<div class="mb-3">
<label class="form-label">Enter double? number</label>
<NumberInput TValue="double?" @bind-Value="@amount6" />
<div class="mt-1">Entered Number: @amount6</div>
</div>

<div class="mb-3">
<label class="form-label">Enter decimal number</label>
<NumberInput TValue="decimal" @bind-Value="@amount7" />
<div class="mt-1">Entered Number: @amount7</div>
</div>

<div class="mb-3">
<label class="form-label">Enter decimal? number</label>
<NumberInput TValue="decimal?" @bind-Value="@amount8" />
<div class="mt-1">Entered Number: @amount8</div>
</div>

@code {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,15 @@
<div class="mb-3">The <code>Step</code> parameter is a number that specifies the granularity that the value must adhere to. Only values that match the specified stepping interval are valid.</div>
<Demo Type="typeof(RangeInput_Demo_04_Step)" Tabs="true" />

<SectionHeading Size="HeadingSize.H2" Text="Decimals" PageUrl="@pageUrl" HashTagName="decimals" />
<div class="mb-3"></div>
<Demo Type="typeof(RangeInput_Demo_05_Decimals)" Tabs="false" />

<SectionHeading Size="HeadingSize.H2" Text="Tick marks" PageUrl="@pageUrl" HashTagName="tick-marks" />
<div class="mb-3">
To add tick marks to a <code>RangeInput</code>, set the <code>TickMarks</code> parameter.
</div>
<Demo Type="typeof(RangeInput_Demo_05_Tick_Marks)" Tabs="true" />


<SectionHeading Size="HeadingSize.H2" Text="Decimals" PageUrl="@pageUrl" HashTagName="decimals" />
<div class="mb-3"></div>
<Demo Type="typeof(RangeInput_Demo_06_Decimals)" Tabs="false" />
<Demo Type="typeof(RangeInput_Demo_06_Tick_Marks)" Tabs="true" />
@code {
private string pageUrl = "/form/range-input";
private string title = "Blazor RangeInput Component";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<RangeInput TValue="decimal" @bind-Value="amount1" Min="0" Max="100" Step="0.01" />
@amount1
<div class="mt-2">@amount1</div>

@code {
decimal amount1 = 0;
}
4 changes: 2 additions & 2 deletions blazorbootstrap/Components/Form/NumberInput/NumberInput.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
id="@ElementId"
class="@ClassNames @fieldCssClasses"
style="@StyleNames"
value="@Value"
value="@GetInvariantNumber(Value)"
step="@Step?.ToString(CultureInfo.InvariantCulture)"
disabled="@Disabled"
placeholder="@Placeholder"
step="@step"
autocomplete="@autoComplete"
@onchange="OnChange"/>
40 changes: 36 additions & 4 deletions blazorbootstrap/Components/Form/NumberInput/NumberInput.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public partial class NumberInput<TValue> : BlazorBootstrapComponentBase
{
#region Fields and Constants

private CultureInfo cultureInfo = default!;

private FieldIdentifier fieldIdentifier;

private string step = default!;
Expand All @@ -24,7 +26,7 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JS.InvokeVoidAsync("window.blazorBootstrap.numberInput.initialize", ElementId, isFloatingNumber(), AllowNegativeNumbers);
await JS.InvokeVoidAsync("window.blazorBootstrap.numberInput.initialize", ElementId, isFloatingNumber(), AllowNegativeNumbers, cultureInfo.NumberFormat.NumberDecimalSeparator);

var currentValue = Value; // object

Expand Down Expand Up @@ -71,6 +73,15 @@ protected override async Task OnInitializedAsync()

step = Step.HasValue ? $"{Step.Value}" : "any";

try
{
cultureInfo = new CultureInfo(Locale);
}
catch (CultureNotFoundException)
{
cultureInfo = new CultureInfo("en-US");
}

await base.OnInitializedAsync();
}

Expand All @@ -84,6 +95,20 @@ protected override async Task OnInitializedAsync()
/// </summary>
public void Enable() => Disabled = false;

private string GetInvariantNumber(TValue value)
{
if (value is null) return string.Empty;

if (value is float floatValue) return floatValue.ToString(CultureInfo.InvariantCulture);

if (value is double doubleValue) return doubleValue.ToString(CultureInfo.InvariantCulture);

if (value is decimal decimalValue) return decimalValue.ToString(CultureInfo.InvariantCulture);

// All numbers without decimal places work fine by default
return value?.ToString() ?? string.Empty;
}

private bool isFloatingNumber() =>
typeof(TValue) == typeof(float)
|| typeof(TValue) == typeof(float?)
Expand Down Expand Up @@ -290,23 +315,23 @@ private bool TryParseValue(object value, out TValue newValue)

if (typeof(TValue) == typeof(float?) || typeof(TValue) == typeof(float))
{
newValue = (TValue)Convert.ChangeType(value, typeof(float));
newValue = (TValue)Convert.ChangeType(value, typeof(float), CultureInfo.InvariantCulture);

return true;
}
// double? / double

if (typeof(TValue) == typeof(double?) || typeof(TValue) == typeof(double))
{
newValue = (TValue)Convert.ChangeType(value, typeof(double));
newValue = (TValue)Convert.ChangeType(value, typeof(double), CultureInfo.InvariantCulture);

return true;
}
// decimal? / decimal

if (typeof(TValue) == typeof(decimal?) || typeof(TValue) == typeof(decimal))
{
newValue = (TValue)Convert.ChangeType(value, typeof(decimal));
newValue = (TValue)Convert.ChangeType(value, typeof(decimal), CultureInfo.InvariantCulture);

return true;
}
Expand Down Expand Up @@ -362,6 +387,13 @@ private bool TryParseValue(object value, out TValue newValue)

private string fieldCssClasses => EditContext?.FieldCssClass(fieldIdentifier) ?? "";

/// <summary>
/// Gets or sets the locale. Default locale is 'en-US'.
/// </summary>
[Parameter]
//[EditorRequired]
public string Locale { get; set; } = "en-US";

/// <summary>
/// Gets or sets the max.
/// Max ignored if EnableMinMax="false".
Expand Down
39 changes: 14 additions & 25 deletions blazorbootstrap/Components/Form/RangeInput/RangeInput.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ public async Task bsOnInput(object? newValue)
/// </summary>
public void Enable() => Disabled = false;

private string GetInvariantNumber(TValue value)
{
if (value is null) return string.Empty;

if (value is float floatValue) return floatValue.ToString(CultureInfo.InvariantCulture);

if (value is double doubleValue) return doubleValue.ToString(CultureInfo.InvariantCulture);

if (value is decimal decimalValue) return decimalValue.ToString(CultureInfo.InvariantCulture);

// All numbers without decimal places work fine by default
return value?.ToString() ?? string.Empty;
}

private async Task HandleChangeAsync()
{
await ValueChanged.InvokeAsync(Value);
Expand Down Expand Up @@ -284,31 +298,6 @@ private void SetValue(object? newValue)
Value = value;
}

private string GetInvariantNumber(TValue value)
{
if (value is null)
{
return string.Empty;
}

if (value is float floatValue)
{
return floatValue.ToString(CultureInfo.InvariantCulture);
}

if (value is double doubleValue)
{
return doubleValue.ToString(CultureInfo.InvariantCulture);
}

if (value is decimal decimalValue)
{
return decimalValue.ToString(CultureInfo.InvariantCulture);
}

// All numbers without decimal places work fine by default
return value?.ToString() ?? string.Empty;
}
private bool TryParseValue(object value, out TValue newValue)
{
try
Expand Down
6 changes: 4 additions & 2 deletions blazorbootstrap/wwwroot/blazor.bootstrap.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,15 @@ window.blazorBootstrap = {
}
},
numberInput: {
initialize: (elementId, isFloat, allowNegativeNumbers) => {
initialize: (elementId, isFloat, allowNegativeNumbers, numberDecimalSeparator) => {
let numberEl = document.getElementById(elementId);

numberEl?.addEventListener('keydown', function (event) {
let invalidChars = ["e", "E", "+"];
if (!isFloat)
if (!isFloat) {
invalidChars.push("."); // restrict '.' for integer types
invalidChars.push(numberDecimalSeparator); // restrict ',' for specific culture
}

if (!allowNegativeNumbers) {
invalidChars.push("-"); // restrict '-'
Expand Down
17 changes: 13 additions & 4 deletions docs/docs/04-forms/number-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Blazor Bootstrap `NumberInput` component is built around HTML input of `type="nu
| AutoComplete | bool | false | | Indicates whether the NumberInput can complete the values automatically by the browser. |
| Disabled | bool | false | | Gets or sets the disabled. |
| EnableMinMax | bool | false | | Determines whether to restrict the user input to Min and Max range. If true, restricts the user input between the Min and Max range. Else accepts the user input. |
| Locale | string | `en-US` | ✔️ | Gets or sets the locale. |
| Max| TValue | | | Gets or sets the max. Max ignored if EnableMinMax="false". |
| Min| TValue | | | Gets or sets the min. Min ignored if EnableMinMax="false". |
| Placeholder | string? | null | | Gets or sets the placeholder. |
Expand All @@ -36,8 +37,8 @@ Blazor Bootstrap `NumberInput` component is built around HTML input of `type="nu

| Name | Description |
|:--|:--|
| Disable | Disables number input. |
| Enable | Enables number input. |
| Disable() | Disables number input. |
| Enable() | Enables number input. |

## Events

Expand Down Expand Up @@ -75,45 +76,53 @@ By default, `e + -` are blocked. For all integral numeric types, dot `.` is bloc

<img src="https://i.imgur.com/iUNBkki.png" alt="Blazor Bootstrap: Number Input Component - Generic type" />

```cshtml {3,8,13,18,23,28,33,38} showLineNumbers
```cshtml {3,9,15,21,27,33,39,45} showLineNumbers
<div class="mb-3">
<label class="form-label">Enter int number</label>
<NumberInput TValue="int" @bind-Value="@amount" />
<div class="mt-1">Entered Number: @amount</div>
</div>

<div class="mb-3">
<label class="form-label">Enter int? number</label>
<NumberInput TValue="int?" @bind-Value="@amount2" />
<div class="mt-1">Entered Number: @amount2</div>
</div>

<div class="mb-3">
<label class="form-label">Enter float number</label>
<NumberInput TValue="float" @bind-Value="@amount3" />
<div class="mt-1">Entered Number: @amount3</div>
</div>

<div class="mb-3">
<label class="form-label">Enter float? number</label>
<NumberInput TValue="float?" @bind-Value="@amount4" />
<div class="mt-1">Entered Number: @amount4</div>
</div>

<div class="mb-3">
<label class="form-label">Enter double number</label>
<NumberInput TValue="double" @bind-Value="@amount5" />
<div class="mt-1">Entered Number: @amount5</div>
</div>

<div class="mb-3">
<label class="form-label">Enter double? number</label>
<NumberInput TValue="double?" @bind-Value="@amount6" />
<div class="mt-1">Entered Number: @amount6</div>
</div>

<div class="mb-3">
<label class="form-label">Enter decimal number</label>
<NumberInput TValue="decimal" @bind-Value="@amount7" />
<div class="mt-1">Entered Number: @amount7</div>
</div>

<div class="mb-3">
<label class="form-label">Enter decimal? number</label>
<NumberInput TValue="decimal?" @bind-Value="@amount8" />
<div class="mt-1">Entered Number: @amount8</div>
</div>
```

Expand Down Expand Up @@ -464,4 +473,4 @@ This event fires on every user keystroke that changes the `NumberInput` value.
}
```

[See demo here](https://demos.blazorbootstrap.com/form/number-input#event-value-changed)
[See demo here](https://demos.blazorbootstrap.com/form/number-input#event-value-changed)
19 changes: 18 additions & 1 deletion docs/docs/04-forms/range-input.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,27 @@ The `Step` parameter is a number that specifies the granularity that the value m

[See demo here](https://demos.blazorbootstrap.com/form/range-input#step)

### Decimals

<img src="https://i.imgur.com/Z6v6dqw.png" alt="Blazor Bootstrap: Range Input Component - Decimals" />

```cshtml {} showLineNumbers
<RangeInput TValue="decimal" @bind-Value="amount1" Min="0" Max="100" Step="0.01" />
<div class="mt-2">@amount1</div>
```

```cs {} showLineNumbers
@code {
decimal amount1 = 0;
}
```

[See demo here](https://demos.blazorbootstrap.com/form/range-input#decimals)

### Tick marks

To add tick marks to a `RangeInput`, set the `TickMarks` parameter.
`

<img src="https://i.imgur.com/dcMBuxT.png" alt="Blazor Bootstrap: Range Input Component - Tick marks" />

```cshtml {3} showLineNumbers
Expand Down
2 changes: 1 addition & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blazorbootstrap",
"version": "2.0.0",
"version": "2.1.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
Expand Down
Loading