Problem
When using LeptonX with Blazorise <Select>, validation runs but the visible select control does not show the validation state.
A required Blazorise text input correctly shows:
- red outline
- validation message
A required Blazorise select on the same form does not show:
- red outline
- validation message
This appears to happen because Blazorise applies validation state and feedback to the native <select>, but LeptonX hides that native element and renders a .custom-select-display proxy. The proxy does not mirror is-invalid, aria-invalid, or aria-describedby, and the validation feedback is not shown visually.
Repro
@page "/leptonx-select-validation-repro"
@using System.ComponentModel.DataAnnotations
<PageTitle>LeptonX Select Validation Repro</PageTitle>
<Card Width="Width.Is25">
<CardHeader>
<Heading Size="HeadingSize.Is4">LeptonX Select Validation Repro</Heading>
</CardHeader>
<CardBody>
<Form>
<Validations @ref="ValidationsRef"
Mode="ValidationMode.Auto"
Model="@Model"
ValidateOnLoad="false">
<Validation>
<Field>
<FieldLabel>Required Text *</FieldLabel>
<TextInput @bind-Value="@Model.RequiredText">
<Feedback>
<ValidationError />
</Feedback>
</TextInput>
</Field>
</Validation>
<Validation>
<Field>
<FieldLabel>Required Select *</FieldLabel>
<Select TValue="string" @bind-Value="@Model.RequiredSelect">
<ChildContent>
<SelectItem Value="@string.Empty"></SelectItem>
<SelectItem Value="@("one")">Option one</SelectItem>
<SelectItem Value="@("two")">Option two</SelectItem>
</ChildContent>
<Feedback>
<ValidationError />
</Feedback>
</Select>
</Field>
</Validation>
</Validations>
<Button Color="Color.Primary" Clicked="ValidateAsync">
Validate
</Button>
</Form>
</CardBody>
</Card>
@code {
private Validations ValidationsRef { get; set; } = new();
private ReproModel Model { get; } = new();
private Task ValidateAsync() => ValidationsRef.ValidateAll();
private sealed class ReproModel
{
[Required(ErrorMessage = "The Required Text field is required.")]
public string? RequiredText { get; set; }
[Required(ErrorMessage = "The Required Select field is required.")]
public string? RequiredSelect { get; set; } = string.Empty;
}
}
2 Answer(s)
-
0
This is a LeptonX theme bug/limitation in the “custom select” overlay implementation: LeptonX hides the native
<select>(where Blazorise appliesis-invalid,aria-invalid,aria-describedby, and where the<ValidationError />feedback is associated) and renders a proxy element (e.g..custom-select-display). The proxy does not mirror the validation state, so you don’t see the red border and the validation message behavior you get withTextInput.Workaround (recommended): avoid the LeptonX custom-select overlay for the affected fields so the real
<select>remains the visible/styled control.- If you can, render a native
<select>(or otherwise ensure the element does not get enhanced by LeptonX’s custom select script/CSS in your setup). - In practice, the simplest workaround is to not use the
form-select-enhanced path for those selects (the LeptonX overlay targets Bootstrap-styled selects). For pages/components where you need Blazorise validation visuals, use a plain select style/class that LeptonX does not transform.
- If you can, render a native
If you must keep LeptonX’s custom select UI, then the only robust fix is on the theme side: LeptonX would need to propagate validation-related classes/attributes from the hidden
<select>to.custom-select-display(and ensure feedback markup is visually associated). There isn’t an ABP-side configuration switch in the provided sources that makes LeptonX do this automatically.
Links (validated):
- https://abp.io/docs/10.4/framework/ui/blazor/forms-validation
- https://blazorise.com/docs/components/validation
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post) -
0
Hi,
Thanks for the clear repro. Confirmed it's a LeptonX issue with the custom-select overlay — the native
<select>is hidden, so Blazorise'sis-invalidclass never reaches the visible proxy element, and the.invalid-feedbacktext stays hidden because it's no longer a sibling of the marked element.While we ship a proper fix in the next release, please drop this small CSS into your project's global stylesheet (e.g.
wwwroot/global-styles.css, or any css that gets bundled after the LeptonX theme):.custom-select-wrapper:has(> select.form-select.is-invalid) .custom-select-display { border-color: var(--bs-form-invalid-border-color, #c00d49) !important; } .custom-select-wrapper:has(> select.form-select.is-invalid) ~ .invalid-feedback { display: block; } .custom-select-wrapper:has(> select.form-select.is-valid) .custom-select-display { border-color: var(--bs-form-valid-border-color, #4fbf67) !important; } .custom-select-wrapper:has(> select.form-select.is-valid) ~ .valid-feedback { display: block; }That gives the proxy a red border and shows the
<ValidationError />message exactly likeTextInputdoes. We'll address it in LeptonX itself so the workaround can be removed in a future release.Thanks.
Markdown supported.Copy, paste, or drag & drop images and files (max 100 MB per file, 100 MB total per post)
