I am trying to build an input box that will always show to 2 decimal places. The model items bound to the component will always be doubles. To clarify what I need, if the text input is 12, the component should automatically format the display to 12.00, or if 12.1 is input it should format the display to 12.10. I should also be able to specify optional minimum and maximum input values and display a validation message if the input value is outside of the boundaries.
I am using blazor server using .net6.
I have created a component that overrides inputbase and for the most part it works ok. User input is detected on blur and the text is then formatted to match the required pattern. What doesn't work is the validation of the input. I have a TryParseValueFromString method which implements my MIN and MAX logic, but this seems to conflict with my onblur logic. It seems I can either get the validation working but not the decimal place display changes or visa versa.
This is my full component code:
@inherits InputBase<double>@using System.Globalization@using System.Text.RegularExpressions@if (!string.IsNullOrWhiteSpace(InputPrompt)){<div class="input-group mb-2" style="@InputGroupStyles" tabindex="0"><span class="input-group-text"> @InputPrompt</span><input @attributes="AdditionalAttributes" style="@Styles" type="text" class="form-control" @bind="@CurrentValueAsString" @oninput=OnInput @onblur=OnBlur /></div>}else{<input @attributes="AdditionalAttributes" style="@Styles" type="text" class="form-control" @bind="@CurrentValueAsString" @oninput=OnInput @onblur=OnBlur />}@code {[Parameter]public string FormatString { get; set; }[Parameter]public double? Min { get; set; }[Parameter]public double? Max { get; set; }[Parameter]public string InputPrompt { get; set; } = string.Empty;[Parameter]public string Styles { get; set; }[Parameter]public string InputGroupStyles { get; set; }[Parameter]public EventCallback ChangeEvent { get; set; }private string stringValue = null;private string _currentValue = null;protected override void OnInitialized(){ this.stringValue = this.FormatValueAsString(this.Value); if (!this.stringValue.Contains(".")) { this.stringValue = this.stringValue +".00"; } base.OnInitialized();}private async Task OnInput(ChangeEventArgs e){ _currentValue = e.Value.ToString();}private async Task OnBlur(){ if(Decimal.TryParse(_currentValue, out decimal dValue)) { stringValue = Math.Round(dValue, 2).ToString("0.00"); this.CurrentValueAsString = stringValue; this.Value = (double)dValue; } ChangeEvent.InvokeAsync();}// Need this to allow input base to receive value if in format other than its default, expanded to allow testing of Min / Max constraintsprotected override bool TryParseValueFromString(string? value, out double result, out string? validationErrorMessage){ if (BindConverter.TryConvertTo<double>(value, System.Globalization.CultureInfo.InvariantCulture, out result)) { if (Min != null) { BindConverter.TryConvertTo<double>(value, CultureInfo.InvariantCulture, out double dValue); if (dValue < Min) { validationErrorMessage = "Value Must be greater than " + Min; return false; } } if (Max != null) { BindConverter.TryConvertTo<double>(value, CultureInfo.InvariantCulture, out double dValue); if (dValue > Max) { validationErrorMessage = "Value Must be less than " + Max; return false; } } validationErrorMessage = null; return true; } else { validationErrorMessage = "Can't parse value"; return false; }}protected override string? FormatValueAsString(double value){ return value.ToString();}} I feel that I am not understanding the order of events and I am probably missing a trick here. Can anyone offer me any advice on how to check those MIN and MAX validation tests and also ensure that the display is giving me the 2 decimal places at all times.Many thanks