Prevent having to click outside of Radzen TextArea for it to register changes

I'm using the Radzen TextArea to have a user enter some text and afterwards they can click a button to Submit this text.

I have my Submit button disabled for as long as TextArea doesn't have any value.
As per my experience and also noticed in the TextArea demo, a user needs to click outside the TextArea for it to register the changes.

Is there a way to prevent that. I want my user to be able to submit the text without him needing to click twice.

Kind regards,
Tino

No, currently this is not possible. Instead of disabling the submit button you can use validation. Clicking the button will blur the textbox and sync the value.

I'm having the same issue in that the last field a user changes before hitting the Submit button is not having its new value updated to the database unless they tab away.

I can't always use validation, for example they may just correct the spelling of a name. Is there any way I can prevent this from happening when the Submit button is clicked?

Hi @SolutionJ,

Clicking the submit button should always blur the text thus update the textbox value. We are not aware of a case when this won't happen. If you have such a scenario please let us know how to reproduce it.

Morning korchev,

The steps to reproduce are:

  1. Edit a record, change the value in a bound text field.

  2. Without clicking away from text field, click the Submit button. Notify message is shown and DataBase is updated correctly.

  3. Alter text field value again.

  4. Repeat step 2. The Notify message is not displayed this time, and the database is not updated.

  5. Without making any further changes, click the Submit button again. This time the Notify message does appear, and the database is updated.

If you repeat the same steps, but this time change the value in, for example, two text boxes, leaving the cursor in the second, only the first text box's value is updated to the database.

Here is my page code:

@page "/customer-card/{id:int}"

@inject NotificationService NS

<ErrorBoundary>

<PageTitle>Customer Card</PageTitle>

<RadzenTemplateForm TItem="Customer" Data="@customer" Submit=OnValidSubmit >

<RadzenStack Orientation="Radzen.Orientation.Vertical">
    <RadzenRow>
        <RadzenColumn>
            <RadzenPanel>
                <RadzenLabel Text="Name" />
                <RadzenRequiredValidator Text="Required" Component="ORG_Name"></RadzenRequiredValidator>
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_Name" Name="ORG_Name"></RadzenTextBox>
                <RadzenLabel Text="Code" />
                <RadzenRequiredValidator Text="Required" Component="ORG_Code"></RadzenRequiredValidator>
                <RadzenTextBox Style="display: block; width: 200px; height: 30px" @bind-Value="@customer.ORG_Code" Name="ORG_Code"></RadzenTextBox>
            </RadzenPanel>
        </RadzenColumn>
        <RadzenColumn>
            <RadzenPanel>
                <RadzenRow>
                    <RadzenLabel Text="Address 1" Style="width: 90px; vertical-align: bottom; height: 30px" />
                    <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_Address1" Name="ORG_Address1"></RadzenTextBox>
                    <RadzenRequiredValidator Text="Required" Component="ORG_Address1"></RadzenRequiredValidator>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Address 2" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_Address2"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Address 3" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_Address3"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Address 4" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_Address4"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="City" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_City"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="County" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_County"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Post Code" Style="width: 90px; height: 30px" />
                <RadzenTextBox Style="display: block; width: 400px; height: 30px" @bind-Value="@customer.ORG_PostCode"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Country" Style="width: 90px; height: 30px" />
                <RadzenDropDown TValue="dynamic" Style="width: 400px; height: 30px"></RadzenDropDown>
                </RadzenRow>
            </RadzenPanel>
        </RadzenColumn>
    </RadzenRow>
<RadzenRow>
        <RadzenColumn Size="6">
            <RadzenPanel Text="Defaults & Settings" Style="font-size:larger;">
                <RadzenRow>
                <RadzenLabel Text="Currency" Style="width: 190px; height: 30px;font-size:medium" />
                <RadzenDropDown TValue="dynamic" Style="width: 200px; height: 30px"></RadzenDropDown>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Margin %" Style="width: 190px; height: 30px;font-size:medium"></RadzenLabel>
                <RadzenTextBox Style="width: 200px; height: 30px"></RadzenTextBox>
                </RadzenRow>
                <RadzenRow>
                <RadzenLabel Text="Sales Price Chase Days" Style="width: 190px; height: 30px;font-size:medium"></RadzenLabel>
                <RadzenTextBox Style="width: 200px; height: 30px"></RadzenTextBox>
                </RadzenRow>
            </RadzenPanel>
        </RadzenColumn>
    </RadzenRow>
</RadzenStack>

<RadzenStack Orientation="Orientation.Horizontal" AlignItems="Radzen.AlignItems.Normal" Style="margin-top: 30px">
    <RadzenButton ButtonStyle="ButtonStyle.Primary" ButtonType="Radzen.ButtonType.Submit" Icon="save" Text="Save" Variant="Variant.Flat" Style="float: none"> </RadzenButton>
    <RadzenButton ButtonStyle="Radzen.ButtonStyle.Danger" Variant="Variant.Flat" Size="ButtonSize.Large" Icon="cancel" Text="Cancel" Click="@Cancel" />
</RadzenStack>

<RadzenCard>
                <RadzenText TextStyle="TextStyle.Subtitle2" TagName="TagName.H3">Info</RadzenText>
</RadzenCard>

</RadzenTemplateForm>

</ErrorBoundary>

@code 
{
    [Parameter]
    public int id { get; set; }

    Customer customer = new Customer();

    protected override async Task OnInitializedAsync()
    {
        if (id > 0) 
        {
            CustomerRepository cusrep = new CustomerRepository(false);
            customer = await Task.Run(() => cusrep.GetById(id));
            DBConnection.DisconnectDB();
        }
    }

    void Cancel()
    {
        //
    }
    //refresh page data

    async void OnValidSubmit()
    {
        
        CustomerRepository cusrep = new CustomerRepository(true); //opens connection to database with transaction if true is passed

        try 
        {
            var result = (false,0,"ok");

            if(customer.ORG_Id == 0)
            {
                result = await cusrep.Add(customer);
            }
            else 
            {
                result = await cusrep.Update(customer);
            }

            if (result.Item1 == true) 
            {
                id = result.Item2;                         
                DBConnection.DisconnectDB(true); //commit transaction and close connection             
                ShowNotification();                   
            }
            else 
            {
               DBConnection.DisconnectDB(false); //rollback transaction and close connection
               ShowNotification();
            }

            CustomerRepository cusrepreread = new CustomerRepository(false);
            customer = await Task.Run(() => cusrepreread.GetById(id));
            DBConnection.DisconnectDB();
        }
        catch (Exception e)
        {

        }
    }

    void ShowNotification()
    {
        NotificationMessage NS = new();
        NS.Severity = NotificationSeverity.Info;
        NS.Summary = "Success";
        NS.Detail = "Customer added or updated";

        NotificationService.Notify(NS);
    }
}

Hi @SolutionJ,

I can't reproduce the described issue by editing this demo. Here is what I observe:

value-change

The value i
The fact that the notification message doesn't show is strange. Even if the value were the same it should have shown. I suspect an exception is being thrown and is caught in the empty catch() {} block. What happens when you debug the application? Can you try logging the exception:

catch (Exception ex)
{
    NotificationService.Notify(new NotificationMessage { Detail = ex.ToString() });
}

Hi korchev,

Ok, I added the suggested code, but it's never triggered. I've since tried taking the Submit= option away from the RadzenTemplateForm tag and instead set a Click option on the Submit button tag. Finally, I've added a notification message at the very start of the Submit code block.

On the first 'Save' on the page, the record is correctly updated even if I leave cursor in the field).

On the second and subsequent 'Save', if the modified field is not tabbed away from, clicking the submit button has no effect - my code block is not triggered (all is well, however, if I do tab away).

Do you mean the Click event of the button or the Submit event of the form? If you handle the Click event of the button it will bypass validation and always execute your handler. Not getting the code to run is very weird and should be related to RadzenTextBox at all. By the way is that code in a dialog by any chance?

Can you reproduce this behavior in the linked demo? It is pretty similar to your scenario and already provides logging support.

I get the same issue whether I use the Submit event of the form or the Click event of the button - I have tried both ways.

No code is in a dialog.

I can't reproduce the behaviour in your linked demo.

Weirdly, if I change nothing at all on the page, the Submit event is triggered, it's only if I change something and do not tab out of the field. In that specific cirumstance, the Submit event is not triggered until the button is clicked twice.

I must admit this is very odd. Could you try something for me? Remove all the code from the Submit handler but the notifications - comment everything else. Does the problem still happen? You can also temporarily remove all validators and basically all other components apart from the offending textbox.

Ok, I've done that, and everything seems ok now - the Submit handler is triggered with every click of the Submit button.

Which one? Removed all your code from the submit handler or every other component but the textbox?

Both. This is all that's left:

@page "/customer-card/{id:int}"

@inject NotificationService NS

Customer Card

@code
{
[Parameter]
public int id { get; set; }

Customer customer = new Customer();

protected override async Task OnInitializedAsync()
{
    try 
    {
        if (id > 0) 
        {
            CustomerRepository cusrep = new CustomerRepository(false);
            customer = await Task.Run(() => cusrep.GetById(id));
            DBConnection.DisconnectDB();
        }
    }
    catch(Exception ex) 
    {
       NotificationService.Notify(new NotificationMessage { Detail = ex.ToString() });
    }
}

void Cancel()
{
    //
}
//refresh page data

async void OnSubmit()
{   
    NotificationService.Notify(new NotificationMessage { Detail = "Reached OnSubmit" });
}

void OnInvalidSubmit(FormInvalidSubmitEventArgs args) 
{
    NotificationService.Notify(new NotificationMessage { Detail = "Reached OnInvalidSubmit" });
}

void ShowNotification()
{
    NotificationMessage NS = new();
    NS.Severity = NotificationSeverity.Info;
    NS.Summary = "Success";
    NS.Detail = "Customer added or updated";

    NotificationService.Notify(NS);
}

}

Thats probably good news - it means that the RadzenTextBox registers the change (which the original thread was about). I am still not sure what could be causing the erratic behavior that you see though. You can try adding back your original code (start with the components first). Please let me know if you find which bit makes it fail.

I've tried it again with the full page layout but no code in the OnSubmit block, and it's being triggered on every click.

This is driving me mad :upside_down_face:

Could you also try removing the error boundary and bringing back your code? And remove the try catch block. If the code in the submit handler is causing the problem there should be an exception. I am also baffled by this issue.

does it work using async Task instead of async void ?

1 Like

Oh my. I completely missed that. There is a very high chance this async void is causing problems.

I discovered that the code was just stopping/hanging when I tried to create a new instance of a respository object, which I was doing in order to retrieve the updated record to 'refresh' the page (specifically, to have available the record's current timestamp).

So, I'm reworking my DB access approach.

Thanks for the input, both of you. As you will be only too well aware, I am very new to Blazor, Radzen, and web programming in general.

Cheers
Reg

You should avoid async void at all costs as it has a lot of drawbacks. For example exceptions that happen in such methods can bring the whole application down.

Before reworking your code I recommend just changing the return type of the method to async Task and seeing what would happen. There is a chance that an exception will be thrown this time with more meaningful information.