I'm developing a web app for a touch panel where no keyboard is available (and I want to avoid the onscreen keyboard). I have tried a number of ways to solve this problem with no joy. My latest attempt is using the Blazor Fluent UI Panel dialog, and I'm close. My last remaining problem is getting the value typed into the number pad returned to the Razor component that opened the number pad. So, the use case is:
- User clicks a form field (FluentTextInput) to enter a numeric value.
- Panel opens on the right side of the screen as a modal dialog.
- User enters a value with buttons that are numbers like a calculator.
- User clicks
OKto use the value orCancelto abort the operation.
Here's my NumPadPanel.razor implementation:
@implements IDialogContentComponent<string>
<FluentDialogBody>
<FluentTextField ReadOnly="true" Style="width: 250px" @bind-Value="Content" /><br />
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 1))">1</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 2))">2</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 3))">3</FluentButton><br />
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 4))">4</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 5))">5</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 6))">6</FluentButton><br />
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 7))">7</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 8))">8</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 9))">9</FluentButton><br />
<FluentButton Class="num-pad-btn" @onclick="ClearInput">Clear</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="@((e) => AddDigit(e, 0))">0</FluentButton>
<FluentButton Class="num-pad-btn" @onclick="Backspace">Backspace</FluentButton><br />
</FluentDialogBody>
@code {
[Parameter]
public string Content { get; set; } = string.Empty;
public void AddDigit(MouseEventArgs e, int digit)
{
Content += digit.ToString();
StateHasChanged();
}
public void ClearInput()
{
Content = string.Empty;
}
public void Backspace()
{
if (Content.Length > 0)
{
Content = Content.Substring(0, Content.Length - 1);
}
}
}
Here's the code for the host component that opens the Panel for input:
<FluentTextField Label="kW Command"
Appearance="FluentInputAppearance.Outline"
Value="@RealPowerCmd"
Style="width: 75px"
@onclick="OpenDialogRealPower" />
@code {
private IDialogReference? _dialog;
private string RealPowerCmd { get; set; } = "0";
private async Task OpenDialogRealPower()
{
var parameters = new DialogParameters<string>()
{
Content = RealPowerCmd,
Alignment = HorizontalAlignment.Right,
PrimaryAction = "OK",
SecondaryAction = "Cancel"
};
_dialog = await DialogService.ShowPanelAsync<NumPadPanel>(RealPowerCmd, parameters);
DialogResult result = await _dialog.Result;
if (result.Cancelled)
{
return;
}
if (result.Data is not null)
{
var inputValue = result.Data as string;
RealPowerCmd = inputValue!;
StateHasChanged();
}
}
}
inputValue does not return the value the user entered.