Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion docs/EditorControls/Button.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/sy
- `CommandName` - the command name passed to `OnCommand` event
- `CommandArgument` - the command argument passed to `OnCommand` event
- `CausesValidation` - controls whether form validation is triggered on click (default: `true`)
- `ValidationGroup` - specifies the validation group for which the button triggers validation
- `Enabled` - enables or disables the button
- `Visible` - controls button visibility
- `ToolTip` - tooltip text displayed on hover
Expand All @@ -28,7 +29,6 @@ Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/sy

- **PostBackUrl** - Not supported; Blazor uses component events instead of postbacks to different pages
- **UseSubmitBehavior** - Not supported; Blazor buttons trigger click events and you can inspect the form regardless
- **ValidationGroup** - Not yet implemented; use EditForm validation instead
- **AccessKey** - Use HTML `accesskey` attribute directly if needed

## Web Forms Declarative Syntax
Expand Down Expand Up @@ -153,6 +153,61 @@ Original Microsoft documentation: https://docs.microsoft.com/en-us/dotnet/api/sy
</EditForm>
```

### ValidationGroup - Selective Validation

The `ValidationGroup` property allows you to create multiple validation groups on a single form. When a button with a `ValidationGroup` is clicked, only validators with the matching `ValidationGroup` will be triggered.

**Important:** To use `ValidationGroup`, you must wrap your form in a `ValidationGroupProvider` component.

```razor
@using BlazorWebFormsComponents.Validations

<ValidationGroupProvider>
<EditForm Model="@model" OnValidSubmit="HandlePersonalSubmit">
@* Personal Information Group *@
<InputText @ref="NameInput.Current" @bind-Value="model.Name" />
<RequiredFieldValidator ControlToValidate="@NameInput"
Text="Name required"
ValidationGroup="Personal" />

<InputText @ref="EmailInput.Current" @bind-Value="model.Email" />
<RequiredFieldValidator ControlToValidate="@EmailInput"
Text="Email required"
ValidationGroup="Personal" />

<Button Text="Validate Personal" ValidationGroup="Personal" />
</EditForm>

<EditForm Model="@model" OnValidSubmit="HandleBusinessSubmit">
@* Business Information Group *@
<InputText @ref="CompanyInput.Current" @bind-Value="model.Company" />
<RequiredFieldValidator ControlToValidate="@CompanyInput"
Text="Company required"
ValidationGroup="Business" />

<Button Text="Validate Business" ValidationGroup="Business" />
</EditForm>
</ValidationGroupProvider>

@code {
ForwardRef<InputBase<string>> NameInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> EmailInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> CompanyInput = new ForwardRef<InputBase<string>>();

private FormModel model = new FormModel();

void HandlePersonalSubmit() { /* Personal validation passed */ }
void HandleBusinessSubmit() { /* Business validation passed */ }
}
```

**How ValidationGroup Works:**

1. **Same Group** - Button with `ValidationGroup="Personal"` triggers only validators with `ValidationGroup="Personal"`
2. **No Group (empty/null)** - Button without a `ValidationGroup` triggers only validators without a `ValidationGroup`
3. **Multiple Groups** - You can have multiple groups on the same page that validate independently
4. **CausesValidation** - Set `CausesValidation="false"` to disable validation entirely for a button

## HTML Output

**Web Forms Input:**
Expand Down
52 changes: 52 additions & 0 deletions docs/ValidationControls/RequiredFieldValidator.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,58 @@ Original Microsoft implementation of the ASP<span></span>.NET RequiredFieldValid

## Features supported in Blazor

- `ControlToValidate` - Reference to the input control to validate (using `ForwardRef<InputBase<T>>`)
- `Text` - Error message displayed inline when validation fails
- `ErrorMessage` - Message shown in ValidationSummary
- `ValidationGroup` - Group name for selective validation (see ValidationGroup section below)
- `Enabled` - Enable or disable the validator
- `Display` - How the error message is displayed (Static, Dynamic, None)
- All style properties (`ForeColor`, `BackColor`, `CssClass`, etc.)

## ValidationGroup Support

The `ValidationGroup` property allows validators to participate in selective validation. When a button with a matching `ValidationGroup` is clicked, only validators in that group will validate.

**Key Points:**

1. Validators and buttons with the same `ValidationGroup` value work together
2. Validators without a `ValidationGroup` are triggered by buttons without a `ValidationGroup`
3. Must wrap form in `<ValidationGroupProvider>` to use `ValidationGroup`

**Example:**

```razor
@using BlazorWebFormsComponents.Validations

<ValidationGroupProvider>
<EditForm Model="@model">
@* This validator is in the "Personal" group *@
<InputText @ref="NameInput.Current" @bind-Value="model.Name" />
<RequiredFieldValidator ControlToValidate="@NameInput"
Text="Name is required"
ValidationGroup="Personal" />

@* This validator is in the "Business" group *@
<InputText @ref="CompanyInput.Current" @bind-Value="model.Company" />
<RequiredFieldValidator ControlToValidate="@CompanyInput"
Text="Company is required"
ValidationGroup="Business" />

@* This button only validates the "Personal" group *@
<Button Text="Validate Personal" ValidationGroup="Personal" />

@* This button only validates the "Business" group *@
<Button Text="Validate Business" ValidationGroup="Business" />
</EditForm>
</ValidationGroupProvider>

@code {
ForwardRef<InputBase<string>> NameInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> CompanyInput = new ForwardRef<InputBase<string>>();
private FormModel model = new FormModel();
}
```

## Web Forms Declarative Syntax

## Usage Notes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Other usage samples:
<NavLink href="./ControlSamples/Button" class="component-link" Match="NavLinkMatch.All">Simple Button</NavLink> |
<NavLink href="./ControlSamples/Button/CausesValidation" class="component-link" Match="NavLinkMatch.All">Causes Validation</NavLink> |
<NavLink href="./ControlSamples/Button/ValidationGroup" class="component-link" Match="NavLinkMatch.All">Validation Group</NavLink> |
<NavLink href="./ControlSamples/Button/JavaScript" class="component-link" Match="NavLinkMatch.All">JavaScript Click</NavLink> |
<NavLink href="./ControlSamples/Button/Style" class="component-link" Match="NavLinkMatch.All">Button Style</NavLink> |
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
@page "/ControlSamples/Button/ValidationGroup"
@using BlazorWebFormsComponents.Validations
@using static BlazorWebFormsComponents.WebColor

<h2>ValidationGroup Demo</h2>

<Nav></Nav>

<p>This demo shows how ValidationGroup allows different buttons to trigger validation for specific sets of validators.</p>

<ValidationGroupProvider>
<EditForm Model="@model" OnValidSubmit="@HandlePersonalSubmit">

<fieldset style="border: 1px solid #ccc; padding: 15px; margin-bottom: 20px;">
<legend>Personal Information (ValidationGroup="Personal")</legend>

<div style="margin-bottom: 10px;">
<Label Text="Name:" AssociatedControlID="name" />
<InputText id="name" @ref="NameInput.Current" @bind-Value="model.Name" style="margin-left: 10px;" />
<RequiredFieldValidator ControlToValidate="@NameInput"
Text="* Name is required"
ErrorMessage="Name is required"
ValidationGroup="Personal"
Display="Dynamic"
ForeColor="Red" />
</div>

<div style="margin-bottom: 10px;">
<Label Text="Email:" AssociatedControlID="email" />
<InputText id="email" @ref="EmailInput.Current" @bind-Value="model.Email" style="margin-left: 10px;" />
<RequiredFieldValidator ControlToValidate="@EmailInput"
Text="* Email is required"
ErrorMessage="Email is required"
ValidationGroup="Personal"
Display="Dynamic"
ForeColor="Red" />
</div>

<Button Text="Validate Personal Info"
CausesValidation="true"
ValidationGroup="Personal"
BackColor="Blue"
ForeColor="White" />
</fieldset>

</EditForm>

<EditForm Model="@model" OnValidSubmit="@HandleBusinessSubmit">

<fieldset style="border: 1px solid #ccc; padding: 15px; margin-bottom: 20px;">
<legend>Business Information (ValidationGroup="Business")</legend>

<div style="margin-bottom: 10px;">
<Label Text="Company:" AssociatedControlID="company" />
<InputText id="company" @ref="CompanyInput.Current" @bind-Value="model.Company" style="margin-left: 10px;" />
<RequiredFieldValidator ControlToValidate="@CompanyInput"
Text="* Company is required"
ErrorMessage="Company is required"
ValidationGroup="Business"
Display="Dynamic"
ForeColor="Red" />
</div>

<div style="margin-bottom: 10px;">
<Label Text="Phone:" AssociatedControlID="phone" />
<InputText id="phone" @ref="PhoneInput.Current" @bind-Value="model.Phone" style="margin-left: 10px;" />
<RequiredFieldValidator ControlToValidate="@PhoneInput"
Text="* Phone is required"
ErrorMessage="Phone is required"
ValidationGroup="Business"
Display="Dynamic"
ForeColor="Red" />
</div>

<Button Text="Validate Business Info"
CausesValidation="true"
ValidationGroup="Business"
BackColor="Green"
ForeColor="White" />
</fieldset>

</EditForm>

<div style="margin-top: 20px;">
<p><strong>Status:</strong> @statusMessage</p>
</div>

</ValidationGroupProvider>

@code {

ForwardRef<InputBase<string>> NameInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> EmailInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> CompanyInput = new ForwardRef<InputBase<string>>();
ForwardRef<InputBase<string>> PhoneInput = new ForwardRef<InputBase<string>>();

private FormModel model = new FormModel();
private string statusMessage = "Ready";

public void HandlePersonalSubmit()
{
statusMessage = $"Personal Info Validated! Name: {model.Name}, Email: {model.Email}";
}

public void HandleBusinessSubmit()
{
statusMessage = $"Business Info Validated! Company: {model.Company}, Phone: {model.Phone}";
}

public class FormModel
{
public string Name { get; set; }

Check warning on line 112 in samples/AfterBlazorServerSide/Components/Pages/ControlSamples/Button/ValidationGroup.razor

View workflow job for this annotation

GitHub Actions / Run Playwright Integration Tests

Non-nullable property 'Name' must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring the property as nullable.
public string Email { get; set; }
public string Company { get; set; }
public string Phone { get; set; }
}

}
Loading
Loading