Completed
Last Updated: 11 Aug 2021 16:10 by ADMIN
Clark
Created on: 01 Jul 2021 21:19
Category: DropDownList
Type: Bug Report
0
DropDownList validation timing is off when using keyboard
I've encountered a scenario where a DropDownList's red border (due to validation status) will be displayed or hidden when it shouldn't. It seems to be always one step behind. For example:

1. Submit the empty form to trigger validation. A validation message is displayed and the field shows a red border as expected.
2. Select a valid value. The validation message goes away as expected, but the red border remains.
3. Select an invalid value. The validation message appears, but now the red border disappears.
4. Select a valid value. The validation message goes away, but the red border remains.

Interestingly, this only happens when using the keyboard. Using the mouse, the border is displayed/hidden at the same time the validation message is displayed/hidden, as would normally be expected.

So to cause this: tab into the field, press one key (e.g., a letter or the down arrow) to select a value, then tab out of the field. If you change the value more than once, the red border will disappear the second time if it is also a valid value.

Animated demo:



I've encountered almost the exact same scenario with other fields when using async validation rules (which Blazor currently does not support), leading me to believe the DropDownList control may be using async somewhere that's resulting in this problem.

Additionally, I'm only experiencing this when I'm wrapping the DropDownList control in my own custom component. I'm not sure why this is.

---

I've included a page and components that demonstrate this problem. It's a little messy but hopefully sheds some light on when it does and doesn't occur. It shows:

1. The issue happens to the TelerikDropDownList when wrapped in a custom component but not otherwise.
2. The issue does not happen to Microsoft's built-in InputSelect even if wrapped in a custom component.
3. The issue does not happen to TelerikTextBox even if wrapped in a custom component.
4. The values of CssClass and InputClass differ, indicating that validation only completes after the value has been changed and OnParametersSet() has been called. (async issue?)

In the attached demo page, the issue only occurs in the last field ("TelerikDropDownListWrapped").

---

Seems like this is a bug with TelerikDropDownList. If not a bug, how can I avoid this issue and why does it not occur with other controls?
Attached Files:
6 comments
ADMIN
Radko
Posted on: 11 Aug 2021 16:10

Hi Clark,

Re where to update the value of the InputCss variable - assigning it outside of the OnParametersSet should do. You can introduce a simple method that returns a string and leave the razor syntax as it is:

@code {
           private string InputCss => $"form-control {CssClass}";
}

As for implementing a custom InputBase or for a better way to accomplish this - it really depends on the specifics of your own product and is rather out of the scope of Telerik components.

Regards, Radko Stanev Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Clark
Posted on: 09 Aug 2021 19:28

@Radko

That's an excellent point about InputCss being inside OnParametersSet, and I suspect that may have been my actual issue. But, where could I put it instead? I feel as though I might have to create my own implementation of InputBase where CssClass is a parameter. Is there a better way?

Clark
Posted on: 26 Jul 2021 14:11
Awesome, thank you for those detailed explanations!
ADMIN
Radko
Posted on: 23 Jul 2021 18:45

Hello Clark,

Yes, exactly. We recommend following the example from the linked Knowledge-Base article which essentially ensures the two-way binding of the parameters.

The underlying implementation of our components follows the same guidelines for validation and binding of parameters as Microsoft. In terms of the inheritance from InputBase, the validation is not attached correctly due to mismatch of the bound value expressions. The FieldIdentifier relies on the ValueExpressions, and in case of differences in these expressions, the validation might be affected because it does not get mapped to object member. Such differences might be a result of nesting components, usage of reflection, or other specific of the framework. 

On a side note, assigning a value to InputCss inside the OnParametersSet event of this component could lead to unexpected behavior as there is no guarantee it will be invoked when you would expect because the CssClass property is not a parameter.

I hope this will bring some clarity to the topic. If you run across any other concerns, please do not hesitate to contact us. We will be happy to step in and assist.

Regards, Radko Stanev Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Clark
Posted on: 16 Jul 2021 20:31

Yes, thank you. Following this example avoids the issue.

Interestingly, it doesn't seem that ValueExpression is necessarily the root cause as the linked article suggests. Even when providing ValueExpression, I still encounter the issue unless the callback I pass to ValueChanged first assigns the value argument to my CBValue property and then calls CBValueChanged.InvokeAsync(v) -- in that order -- as is done in the linked example:

    async Task RaiseValueChanged(T v)
    {
        // two-way binding for the current component, and raising an event that provides
        // two-way binding for the parent component. We can't use @bind-Value here because
        // we want to explicitly set the ValueExpression for the validation
        CBValue = v;
        if (CBValueChanged.HasDelegate)
        {
            await CBValueChanged.InvokeAsync(CBValue);
        }
    }

Normally that's not necessary to assign explicitly. For some reason, if I don't assign that explicitly, and do so before calling CBValueChanged.InvokeAsync(), I still experience the problem.

In my case, my component inherits from InputBase, so I am assigning to CurrentValue, which internally calls ValueChanged.InvokeAsync() itself, but I still have to call that explicitly too. This issue only seems to happen when inheriting from InputBase, too.

So I don't know if it's ultimately a bug with InputBase, a bug with TelerikDropDownList, or not a bug at all but just a coincidence. I don't know why it doesn't seem to be an issue with other controls like TelerikTextBox. I wish I could understand the exact cause so I can be confident this solution solves the problem, but it does seem to avoid the problem so thank you for that. Even though I'm not having this problem with other controls, I assume I should similarly use Value/ValueChanged/ValueExpression in the same way with all of them just to be safe?

ADMIN
Svetoslav Dimitrov
Posted on: 08 Jul 2021 13:21

Hello Clark,

We have a Knowledge-based article that covers the scenario when you would like to validate a child input component. Could you take a look at the explanations and examples there and see if this helps you move forward with your application? If it does not get back to me so that our team can offer a different solution. 

Regards,
Svetoslav Dimitrov
Progress Telerik

Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.