forked from MudBlazor/MudBlazor
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MudFileUpload: Improve validation in MudForm (MudBlazor#7720)
* MudFileUpload: Allow clearing FileUpload by setting `Files` to null Builds upon MudBlazor#7578 to flesh out form validation on `MudFileUpload` by allowing users to clear a `MudFileUpload` instance by setting `Files` to `null`. This would previously not trigger form validation or it would not mark the `MudFileUpload` instance as `Touched`. * WIP `ClearAsync` + `FileUploadButtonTemplateContext` implementations * Add/Update documentation and tests
- Loading branch information
1 parent
4e07fa4
commit 59f7e62
Showing
24 changed files
with
562 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
...ocs/Pages/Components/FileUpload/Examples/FileUploadDragAndDropCustomScenarioExample.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
@namespace MudBlazor.Docs.Examples | ||
|
||
@inject ISnackbar Snackbar | ||
|
||
<MudStack Style="width: 100%"> | ||
<MudFileUpload T="IReadOnlyList<IBrowserFile>" | ||
AppendMultipleFiles | ||
OnFilesChanged="OnInputFileChanged" | ||
Hidden="@false" | ||
InputClass="absolute mud-width-full mud-height-full overflow-hidden z-20" | ||
InputStyle="opacity:0" | ||
@ondragenter="@SetDragClass" | ||
@ondragleave="@ClearDragClass" | ||
@ondragend="@ClearDragClass"> | ||
<ButtonTemplate> | ||
<MudPaper Height="300px" | ||
Outlined="true" | ||
Class="@_dragClass"> | ||
<MudText Typo="Typo.h6"> | ||
Drag and drop files here or click | ||
</MudText> | ||
@foreach (var file in _fileNames) | ||
{ | ||
<MudChip Color="Color.Dark" Text="@file" /> | ||
} | ||
</MudPaper> | ||
<MudToolBar DisableGutters="true" | ||
Class="relative d-flex justify-end gap-4 z-30"> | ||
<MudButton HtmlTag="label" | ||
Color="Color.Primary" | ||
for="@context.Id" | ||
Variant="Variant.Filled"> | ||
Open file picker | ||
</MudButton> | ||
<MudButton OnClick="@Upload" | ||
Color="Color.Primary" | ||
Disabled="@(!_fileNames.Any())" | ||
Variant="Variant.Filled"> | ||
Upload | ||
</MudButton> | ||
<MudButton OnClick="@Clear" | ||
Color="Color.Error" | ||
Disabled="@(!_fileNames.Any())" | ||
Variant="Variant.Filled"> | ||
Clear | ||
</MudButton> | ||
</MudToolBar> | ||
</ButtonTemplate> | ||
</MudFileUpload> | ||
</MudStack> | ||
|
||
@code { | ||
#nullable enable | ||
private const string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full z-10"; | ||
private string _dragClass = DefaultDragClass; | ||
private readonly List<string> _fileNames = new(); | ||
|
||
private async Task Clear() | ||
{ | ||
_fileNames.Clear(); | ||
ClearDragClass(); | ||
await Task.Delay(100); | ||
} | ||
|
||
private void OnInputFileChanged(InputFileChangeEventArgs e) | ||
{ | ||
ClearDragClass(); | ||
var files = e.GetMultipleFiles(); | ||
foreach (var file in files) | ||
{ | ||
_fileNames.Add(file.Name); | ||
} | ||
} | ||
|
||
private void Upload() | ||
{ | ||
// Upload the files here | ||
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; | ||
Snackbar.Add("TODO: Upload your files!"); | ||
} | ||
|
||
private void SetDragClass() | ||
=> _dragClass = $"{DefaultDragClass} mud-border-primary"; | ||
|
||
private void ClearDragClass() | ||
=> _dragClass = DefaultDragClass; | ||
} |
60 changes: 0 additions & 60 deletions
60
src/MudBlazor.Docs/Pages/Components/FileUpload/Examples/FileUploadDragAndDropExample.razor
This file was deleted.
Oops, something went wrong.
113 changes: 113 additions & 0 deletions
113
...Pages/Components/FileUpload/Examples/FileUploadDragAndDropWithFormValidationExample.razor
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
@using System.IO | ||
@using System.Text | ||
@using System.Threading | ||
@using FluentValidation | ||
|
||
@namespace MudBlazor.Docs.Examples | ||
|
||
@inject ISnackbar Snackbar | ||
|
||
<MudStack Style="width: 100%"> | ||
<MudForm Model="@_model" | ||
@bind-IsValid="_isValid" | ||
@bind-IsTouched="_isTouched" | ||
Validation="@_validationRules.ValidateValue"> | ||
<MudItem xs="12"> | ||
<MudFileUpload T="IReadOnlyList<IBrowserFile>" | ||
AppendMultipleFiles | ||
@bind-Files="_model.Files" | ||
@bind-Files:after="@ClearDragClass" | ||
For="@(() => _model.Files)" | ||
Hidden="@false" | ||
InputClass="absolute mud-width-full mud-height-full overflow-hidden z-20" | ||
InputStyle="opacity:0" | ||
@ondragenter="@SetDragClass" | ||
@ondragleave="@ClearDragClass" | ||
@ondragend="@ClearDragClass"> | ||
<ButtonTemplate> | ||
<MudPaper Height="300px" | ||
Outlined="true" | ||
Class="@_dragClass"> | ||
<MudText Typo="Typo.h6"> | ||
Drag and drop files here or click | ||
</MudText> | ||
@foreach (var file in _model.Files?.Select(file => file.Name) ?? Enumerable.Empty<string>()) | ||
{ | ||
<MudChip Color="Color.Dark" | ||
Text="@file" /> | ||
} | ||
</MudPaper> | ||
<MudToolBar DisableGutters="true" | ||
Class="relative d-flex justify-end gap-4 z-30"> | ||
<MudButton HtmlTag="label" | ||
Color="Color.Primary" | ||
for="@context.Id" | ||
Variant="Variant.Filled"> | ||
Open file picker | ||
</MudButton> | ||
<MudButton OnClick="@Upload" | ||
Color="Color.Primary" | ||
Disabled="@(!_isValid || !_isTouched || _model.Files is null || !_model.Files.Any())" | ||
Variant="Variant.Filled"> | ||
Upload | ||
</MudButton> | ||
<MudButton OnClick="@context.Actions.ClearAsync" | ||
Color="Color.Error" | ||
Disabled="@(_model.Files is null || !_model.Files.Any())" | ||
Variant="Variant.Filled"> | ||
Clear | ||
</MudButton> | ||
</MudToolBar> | ||
</ButtonTemplate> | ||
</MudFileUpload> | ||
</MudItem> | ||
<MudItem xs="12"> | ||
IsValid: @_isValid - IsTouched: @_isTouched | ||
</MudItem> | ||
</MudForm> | ||
</MudStack> | ||
|
||
@code { | ||
#nullable enable | ||
public class Model | ||
{ | ||
public IReadOnlyList<IBrowserFile>? Files { get; set; } = new List<IBrowserFile>(); | ||
} | ||
|
||
private Model _model = new(); | ||
private ModelFluentValidator _validationRules = new(); | ||
private bool _isValid; | ||
private bool _isTouched; | ||
private const string FileContent = "this is content"; | ||
private const string DefaultDragClass = "relative rounded-lg border-2 border-dashed pa-4 mt-4 mud-width-full mud-height-full z-10"; | ||
private string _dragClass = DefaultDragClass; | ||
|
||
private void Upload() | ||
{ | ||
// Upload the files here | ||
Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; | ||
Snackbar.Add("TODO: Upload your files!"); | ||
} | ||
|
||
private void SetDragClass() | ||
=> _dragClass = $"{DefaultDragClass} mud-border-primary"; | ||
|
||
private void ClearDragClass() | ||
=> _dragClass = DefaultDragClass; | ||
|
||
public class ModelFluentValidator : AbstractValidator<Model> | ||
{ | ||
public ModelFluentValidator() | ||
{ | ||
RuleFor(x => x.Files) | ||
.NotEmpty() | ||
.WithMessage("There must be at least 1 file."); | ||
} | ||
|
||
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) => | ||
{ | ||
var result = await ValidateAsync(ValidationContext<Model>.CreateWithOptions((Model)model, x => x.IncludeProperties(propertyName))); | ||
return result.IsValid ? Array.Empty<string>() : result.Errors.Select(e => e.ErrorMessage); | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.