Recognize + and - as control characters in RadzenTextBox

I tricked the RadzenTextBox into allowing Control Characters that a Prevent Default-ed from showing in the field.

I have a small form with, among others, a quantity field. and 2 radio buttons for X Full and X Partial In the application I'm replacing. This is a volume scanning operation so the operator scans and then enters the quantity and presses "+" if the radio button needs to change to full or:"-" to change to Partial as a time-saving shortcut.

I came across this syncfusion page and it worked, however, only in this manner:

I actually made it work, but I can't build it for I get RZ10010 errors.

Severity Code Description Project File Line Suppression State
Error (active) RZ10010 The component parameter 'onkeydown' is used two or more times for this component. Parameters must be unique (case-insensitive). The component parameter 'onkeydown' is generated by the '@onkeydown:preventDefault' directive attribute. C:\DotNetPLI\ProphetX\ProphetXBlazorServerWithAuth\ProphetXBlazorServerWithAuth\Pages\Warehouse\ReturnMain.razor 524

Now comes the kicker, even though the error was generated, Hot Reload rebuilt the app with the added @onkeydown:preventdefault and after the screen refreshed, it worked as I'd hoped. I guess it just went ahead and added it to html.

This resulting in the behavior that I am seeking.

Is it possible that the RZ10010 is a little too tight. It appears that allowing @onkeydown:PreventDefault =(Boolean) works for stripping out characters.

Perhaps theres a bretter way.
Thank you

I accidentaly found it working when I added

@onkeydown="@onKeydown"
@onkeydown:preventDefault="@isPreventKey"

I am afraid I don't understand what you are asking.

1 Like

Yes sir, I apologize for being unclear. I'm asking if there's any way to make the following code not generate an error? Using the followng creates a RZ10010 error in the build. The second line below causes the error. I actually would like to be able to use this construct..

@onkeydown="@onKeydown"
@onkeydown:preventDefault="@isPreventKey"

onKeyDown checks for a "+'": or a :"-" if true sets isPreventKey = true.
The preventDefautl is observeed and the characters are prevented from being typed into the field.

I want to process a function for + and - and have them not appear in whatever text field the user is in. + and - will change a radio button.

I forced this to work by adding the prevent default line while running then hitting hot reload. It generated the working code even though the error was shown. It did produce the desired functinality. I just can't build it.

I hope that's more clear. If not I can probably send a project to check.
thank you

That's a Blazor issue I am afraid: Blazor WASM event:preventDefault on Components ยท Issue #18460 ยท dotnet/aspnetcore ยท GitHub

You will have to use a regular <input />. You can style it as RadzenTextBox by setting its class attribute

<input class="rz-textbox" @onkeydown=".." @onkeydown:preventDefault />
1 Like

Thank You, Korchev,

one more question if I may?

The perfect answer would be to be able to strip these 2 control characters out of input at a form level rather than for each control individually. Do you think that's possible? Perhaps using EditForm instead of RadzenTempateForm? I tried just hanging it on a containing

but isn't working that way.

You can easily remove those characters from the input before saving the data to your database. We don't have a different solution other the the already suggested one.

It's hard to get the same response in a web form that they get in WinForms.
As you said its a Blazor issue, the Input statement generates the same error.
I may have to try integrating some javascript. Thank you for your help.

A JavaScript solution should work better. You can try something like this:

<RadzenTextBox onkeydown="onKeyDown" .../>

where the onKeyDown JS function is something like:

function onKeyDown(event) {
   if (event.key == '+') {
      event.preventDefault();
   }
}
1 Like

I have created a working, self-contained example solution to prevent "+" and "-" characters from appearing. yet still be able to act on them as control characters, solving the need expressed in this thread. Below are three examples in code, a small parent form, the razor form component and a snippet of JavaScript.

You can press + or - in either field and the Radio button will change to 'full' for '+' and 'empty' for '-'.

Parent Form:

 @page "/ittools/plusminus"
 <h3>Plus/Minus</h3>
 
 <div class="row">
     <div class="col">
 
         <PlusMinusForm />
 
     </div>
     <div class="col">
         <p>
             The idea is you press + to change to 'full' and - to change to 'empty'
         </p>
 
     </div>
 </div>

Below is the Component Form Code, with an example of RadzenTextBox and InputText:

@inject IJSRuntime JS
@implements IDisposable

<EditForm Model="@model" OnValidSubmit="@HandleValidSubmit">
    <div class="row">
        <div class="col">

            <label>Lot No:</label>
            <RadzenTextBox @bind-Value="model.LotNo" @onkeydown="@KeyDown" @ref="refLotNo" />
        </div>
    </div>
    <div class="row">
        <div class="col">

            <label>Quantity:</label>
            <InputText @bind-Value="model.Quantity" @onkeydown="@KeyDown" @ref="refQuantity" />
        </div>
    </div>
    <div class="row">
        <div class="col">
            <label>Quantity Type:</label>
            <div>
                <input type="radio" id="full" name="quantityType" value="full" @onchange="@(()=>{model.QuantityType = "full";})" checked="@model.QuantityType.Equals("full")" />
                <label for="full">Full</label>
            </div>
            <div>
                <input type="radio" id="empty" name="quantityType" value="empty" @onchange="@(()=>{model.QuantityType = "empty";})" checked="@model.QuantityType.Equals("empty")" />
                <label for="empty">Partial</label>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col">
            <RadzenButton ButtonType="ButtonType.Submit" Text="Submit" />
        </div>
    </div>
</EditForm>

<div class="row">
    <div class="col">
        <p>            
            Quantity: @model.Quantity <br />
            Quantity Type: @model.QuantityType <br />
        </p>
    </div>
</div>


@code {
    private ExampleModel model = new ExampleModel();

    private RadzenTextBox? refLotNo;
    private InputText? refQuantity;

    private DotNetObjectReference<PlusMinusForm>? objRef;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            objRef = DotNetObjectReference.Create(this);

            await JS.InvokeVoidAsync("exampleJsFunctions.addKeyDownEventListener", refLotNo!.Element, objRef);
            await JS.InvokeVoidAsync("exampleJsFunctions.addKeyDownEventListener", refQuantity!.Element, objRef);
        }
    }

    public void Dispose()
    {        
        JS.InvokeVoidAsync("exampleJsFunctions.removeKeyDownEventListener", refQuantity);
        JS.InvokeVoidAsync("exampleJsFunctions.removeKeyDownEventListener", refLotNo);
        objRef?.Dispose();
    }

    private void KeyDown(KeyboardEventArgs e)
    {
        if (e.Code is "NumpadAdd" or "NumpadSubtract")
        {
            model.QuantityType = e.Code is "NumpadAdd" ? "full" : "empty";
            return;
        }        
    }

    private async Task HandleValidSubmit()
    {
        // Do something with the submitted data
        await Task.CompletedTask;
    }
    public class ExampleModel
    {        
        public string? LotNo { get; set; }
        public string? Quantity { get; set; }
        public string? QuantityType { get; set; } = "full";
    }
}

Then the glue that makes it all work, I placed the following content into my site.js file


 window.exampleJsFunctions = {
     addKeyDownEventListener: function (element, dotNetObject) {
         element.addEventListener('keydown', event => {
             if (event.code === 'NumpadAdd' || event.code === 'NumpadSubtract') {
                 event.preventDefault();
                 dotNetObject.invokeMethodAsync('KeyDown', event.code);
             }
         });
     },
     removeKeyDownEventListener: function (element) {
         element.removeEventListener('keydown');
     }
 };
1 Like