0
votes

La couleur de la bordure n'est pas modifiée lorsque le champ n'est pas valide

Je suis assez nouveau sur Blazor. J'essaie de rendre un composant personnalisé dans EditForm en faisant référence à cette page.

Mais lorsque je soumets le formulaire sans valeur, la couleur de la bordure n'est pas changée en rouge. De même, lors de la soumission du formulaire après avoir effacé la valeur saisie, la bordure n'a pas changé en rouge. Il reste en vert.

Capture d'écran:

image

Extrait de code

NativeTextboxComponent.razor

<EditForm Model="@model" OnInvalidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <NativeTextBoxComponent @bind-Value="@model.NativeValue"></NativeTextBoxComponent>
    <ValidationMessage For="() => model.NativeValue" />
    <button type="submit">Submit</button>
</EditForm>

public class Countries
    {
        [Required]
        public string Values { get; set; }
        [Required]
        public string LastName { get; set; }
        [Required]
        public string NativeValue { get; set; }
    }
    public Countries model = new Countries();

Index.razor

<InputText @bind-Value="@Value" class="form-control" />

@code {
 public string _Value;
    [Parameter]
    public string Value
    {
        get
        {
            return _Value;
        }
        set
        {
            if (_Value != value)
            {
                ValueChanged.InvokeAsync(value);
            }
            _Value = value;
        }
    }
    [Parameter]
    public EventCallback<string> ValueChanged { get; set; }

}
}

FieldCssClass est retourné modifié valide pour ce cas.

image

Toute aide serait grandement appréciée.


1 commentaires

Je ne sais pas pourquoi ce problème se produit, mais la solution préférée pour un tel scénario est d'hériter de InputBase <T> plutôt que d'encapsuler un InputText


3 Réponses :


0
votes

Pour comprendre pourquoi FieldCssClass renvoie valide et ValidationMessage renvoie invalide, il est important d'observer votre composant NativeTextboxComponent fait au processus de validation.

Dans votre exemple, si vous changez votre NativeTextBoxComponent en InputText, cela fonctionnera correctement. C'est parce que le @ bind-value définit la ValueExpression de InputBase. Cette propriété n'est pas une simple chaîne mais une expression. Cette expression est utilisée pour obtenir les attributs de votre modèle, comme Requis.

Si vous utilisez votre <NativeTextBoxComponent @bind-Value="@model.NativeValue"></NativeTextBoxComponent> une chaîne simple est liée au composant. Il a perdu son lien avec ses attributs. La liaison bidirectionnelle fonctionne toujours. Si votre composant modifie la chaîne, il est réécrit dans l'objet. C'est la raison pour laquelle votre <ValidationMessage For="() => model.NativeValue" /> renvoie une erreur, s'il n'y a pas de chaîne. Mais encore une fois, du point de vue de votre <InputText @bind-Value="@Value" class="form-control" /> imbriqué, il ne s'agit que d'une chaîne.

Pour résoudre votre problème, votre composant peut hériter d'InputBase et vous pouvez créer votre disposition personnalisée.

@using System.Diagnostics.CodeAnalysis;

@inherits InputBase<string>

<input @attributes="AdditionalAttributes" class="@CssClass" @bind-value="CurrentValue" />

@code {

    protected override bool TryParseValueFromString(string? value, out string? result, [NotNullWhen(false)] out string? validationErrorMessage)
    {
        result = value;
        validationErrorMessage = null;
        return true;
    }
}


0 commentaires

0
votes

Je pense qu'il vous manque le modèle dans lequel vous mettez le champ requis. Voici un exemple tiré de la documentation ici

using System.ComponentModel.DataAnnotations;

public class ExampleModel
{
    [Required]
    [StringLength(10, ErrorMessage = "Name is too long.")]
    public string Name { get; set; }
}


0 commentaires

0
votes

ValueExpression est défini en tant que paramètre, de sorte que le modèle de composant parent n'est pas mis à jour en expression de composant enfant, donc la valeur du modèle n'est pas mise à jour dans FieldIdentifier cssClass. Lors du rendu du composant personnalisé à l'intérieur du formulaire d'édition, appelez directement invokeAsync et value expression (pas besoin d'utiliser two-bind (@ bind-Value)).

Index.razor

<InputText Value="@Value" ValueChanged="ValueChanged" @oninput="@InputHandler" ValueExpression="@ValueExpression"></InputText>
@code
{ 
private string _value { get; set; }
[Parameter]
public string ID { get; set; }
[Parameter]
public Expression<Func<string>> ValueExpression { get; set; }
[Parameter]
public string Value
{
    get => _value;
    set
    {
        if (!EqualityComparer<string>.Default.Equals(value, _value))
        {
            _value = value;
            ValueChanged.InvokeAsync(value);
        }
    }
}
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> InputHandler { get; set; }

}

NativeTextboxComponent.razor

<EditForm Model="@model">
      <DataAnnotationsValidator />
      <h5>TextBox : @model.FirstName</h5>
    <NativeTextBoxComponent @bind-Value="@model.FirstName" InputHandler="@inputHandler"> </NativeTextBoxComponent >
    <ValidationMessage For="() => model.FirstName" />
   <SfButton CssClass="e-small e-info" Type="submit" Content="Submit"></SfButton>
</EditForm>
@code {
public class Countries
{
    [Required]
    public string FirstName { get; set; }
}
public Countries model = new Countries();

private void inputHandler(ChangeEventArgs args)
{
    model.FirstName = (string)args.Value;
}

}


0 commentaires