Blazor InputText with Required attribute but Disabled

1.8k Views Asked by At

So I have a model, other properties removed for brevity:

public class OutOfLimitReasonViewModel
{
  
  [Required]
  public int ReasonId { get; set; }
  
  [Required(ErrorMessage = "Other Reason is required")]
  public string OtherReason { get; set; }
}

Of course I have an EditForm on the .razor page and the InputText I care about looks like this:

<InputText @bind-Value="model.OtherReason" class="form-control" disabled="@(!OtherReasonRequired)" />
<ValidationMessage For="@(() => model.OtherReason)" />

There is also a select that has the list of available Reason objects, one of which is Other. I do have a property called OtherReasonRequired which graphically does what I want (either Enable or Disable the input based on if the selected Reason == "Other") so that code works:

public bool OtherReasonRequired
{
  get
  {
    var result = false;

    if (model.ReasonId > 0)
    {
      var reason = Reasons.Find(x => x.Id == model.ReasonId);
      result = reason.Reason == "Other";
    }

    return result;
  }
}

This works perfectly if I select Other and give OtherReason a value, the Save/Submit button is valid and it works.

My issue is when I have NOT selected Other. Graphically, the InputField does get disabled and grayed out. But the Save/Submit believes the model is invalid because there is no value in the OtherReason field.

Is there something I can do to get this to work?

Would love to have a dynamic attribute called RequiredIf.

But logically to me, I see this as a bug. If a control is disabled, it's value is irrelevant in my mind.

1

There are 1 best solutions below

0
On

Please check the following. I don't use any of the built-in Data Annotation, but it's still very easy to check the input and let the user know what I want them to do:

<EditForm Model="@DisplayModel" OnValidSubmit="HandleValidSubmit" >
        <InputRadioGroup TValue=int? @bind-Value=DisplayModel.ReasonID>
            @for (int i=1; i< Reasons.Count(); i++){
                <InputRadio Value=Reasons[i].ID /> @Reasons[i].Description <br/>
            }
            <InputRadio Value=0 />Other <br/>
        </InputRadioGroup>
        <input @bind=DisplayModel.OtherText disabled=@((DisplayModel.ReasonID??1) !=0 ) />
        <button type="submit">Submit</button>
        <div class="text-danger">@DisplayMessage</div>
    </EditForm>

@code {
    string DisplayMessage="";

    class Reason { public int? ID; public string? Description; }
    List<Reason> Reasons = new List<Reason> {
            new Reason { ID = 0, Description = "Other"},
            new Reason { ID = 1, Description = "You're lame" },
            new Reason { ID = 2, Description = "I'm too busy" }
    };
    class MyDisplayModel
    {
        public int? ReasonID;
        public string OtherText="";
    }
    MyDisplayModel DisplayModel = new MyDisplayModel();
    private async Task HandleValidSubmit()
    {
        if(DisplayModel.ReasonID is not null) if (DisplayModel.ReasonID==0) if (DisplayModel.OtherText == "")
            {
                DisplayMessage = "You must type a description of your issue.";
                StateHasChanged();
                await Task.Delay(1500);
                DisplayMessage = "";
            }
    }
}