Skip to content

Commit 154a6ee

Browse files
authored
983306: Re-structing the form integration section of File uploader.
1 parent 18a06aa commit 154a6ee

File tree

3 files changed

+63
-116
lines changed

3 files changed

+63
-116
lines changed

blazor/file-upload/form-integration.md

Lines changed: 63 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -9,200 +9,147 @@ documentation: ug
99

1010
# Form Integration in Blazor File Upload Component
1111

12-
The Syncfusion Blazor File Upload component can be integrated with Blazor's `EditForm` and `DataForm` to build robust forms that include file-handling capabilities. This allows you to associate file uploads with a model and trigger validation.
12+
The Syncfusion Blazor File Upload component seamlessly integrates with Blazor's [EditForm](https://learn.microsoft.com/en-us/aspnet/core/blazor/forms/?view=aspnetcore-9.0) and the Syncfusion [DataForm](https://blazor.syncfusion.com/documentation/data-form/getting-started-with-web-app), enabling you to build robust forms with file upload functionality. This integration associates the uploaded file information with a data model, leveraging the form's built-in validation.
1313

14-
In a form, file validation is triggered by populating a model property when a file is selected and clearing it when removed. The `FileSelected` and `OnRemove` events are used for this purpose. When the form is submitted, the file can be uploaded manually to a server-side endpoint.
14+
When a file is selected, its information is added to the model property bound to the component. Upon form submission, the entire model, including the list of selected files, is passed to the submit event handler.
1515

1616
## File Upload with EditForm Integration
1717

18-
The File Upload component can be integrated into a Blazor `EditForm` to manage file uploads as part of your data entry process.
18+
Integrating the File Upload component into a Blazor `EditForm` streamlines data entry by including file management directly within the form.
1919

20-
To validate the file input, a model property is updated using the `FileSelected` and `OnRemove` events. The file upload is initiated only when the form is valid by calling the `UploadAsync` method in the `OnValidSubmit` event handler.
20+
Validation for the file input is achieved by binding the component to a model property. The [ValueChange](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.UploaderEvents.html#Syncfusion_Blazor_Inputs_UploaderEvents_ValueChange) and [OnRemove](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Inputs.UploaderEvents.html#Syncfusion_Blazor_Inputs_UploaderEvents_OnRemove) events are used to update this property with the current list of files. Within these events, it is crucial to call `EditContext.NotifyFieldChanged` to trigger the form's validation logic immediately after the file list changes.
2121

22-
### Uploading to a Server-Side API (Blazor WASM and Server)
23-
24-
This example shows how to configure the File Upload component to send files to a server-side API endpoint upon form submission. This approach is compatible with both Blazor WebAssembly and Blazor Server applications.
22+
When the form is successfully submitted, the `OnValidSubmit` event handler receives the `EditContext`, which contains the complete form model.
2523

2624
```cshtml
2725
@using System.ComponentModel.DataAnnotations
2826
@using Syncfusion.Blazor.Inputs
27+
@using Syncfusion.Blazor.Buttons
2928
30-
<EditForm Model="@employee" OnValidSubmit="@HandleValidSubmit">
29+
<EditForm Model="@employee" OnValidSubmit="@HandleValidSubmit" Context="formContext">
3130
<DataAnnotationsValidator />
3231
<div class="form-group">
33-
<SfUploader @ref="UploadObj" AllowMultiple="false" AutoUpload="false" ID="UploadFiles">
34-
<UploaderAsyncSettings SaveUrl="https://blazor.syncfusion.com/services/production/api/FileUploader/Save"
35-
RemoveUrl="https://blazor.syncfusion.com/services/production/api/FileUploader/Remove"></UploaderAsyncSettings>
36-
<UploaderEvents OnRemove="OnRemove" FileSelected="OnSelect"></UploaderEvents>
32+
<SfUploader @ref="@UploaderObj" ID="UploadFiles">
33+
<UploaderEvents ValueChange="@(async (args) => await OnChange(args, formContext))" OnRemove="@(async (args) => await OnRemove(args, formContext))"></UploaderEvents>
3734
</SfUploader>
3835
<ValidationMessage For="() => employee.files" />
3936
</div>
40-
<button type="submit" class="btn btn-primary">Submit</button>
37+
<SfButton type="submit" CssClass="e-primary">Submit</SfButton>
4138
</EditForm>
4239
4340
@code {
44-
private SfUploader UploadObj;
45-
46-
public class Employee
47-
{
48-
[Required(ErrorMessage = "Please upload a file")]
49-
public List<UploaderUploadedFiles> files { get; set; }
50-
}
51-
52-
public Employee employee = new Employee();
53-
54-
public void OnSelect(SelectedEventArgs args)
55-
{
56-
this.employee.files = new List<UploaderUploadedFiles> { new UploaderUploadedFiles { Name = args.FilesData[0].Name, Type = args.FilesData[0].Type, Size = args.FilesData[0].Size } };
57-
}
58-
59-
public void OnRemove()
60-
{
61-
this.employee.files = null;
62-
}
63-
64-
public async Task HandleValidSubmit()
65-
{
66-
// Upload the selected file manually only when the form is valid
67-
await this.UploadObj.UploadAsync();
68-
}
69-
}
70-
```
71-
72-
### Saving Files Directly to the File System (Blazor Server Only)
73-
74-
In a Blazor Server application, you can save uploaded files directly to the server's file system. The following example demonstrates how to use the `ValueChange` event to read the file stream and save it to a path.
75-
76-
> This method writes files to the server's local file system and is only supported in Blazor Server applications. It will not work in a Blazor WebAssembly environment.
77-
78-
```cshtml
79-
@using System.ComponentModel.DataAnnotations
80-
@using Syncfusion.Blazor.Inputs
81-
82-
<EditForm Model="@employee" OnValidSubmit="@HandleValidSubmit">
83-
<DataAnnotationsValidator />
84-
<div class="form-group">
85-
<SfUploader @ref="UploadObj" AllowMultiple="false" AutoUpload="false" ID="UploadFiles">
86-
<UploaderEvents ValueChange="OnChange" OnRemove="OnRemove" FileSelected="OnSelect"></UploaderEvents>
87-
</SfUploader>
88-
<ValidationMessage For="() => employee.files" />
89-
</div>
90-
<button type="submit" class="btn btn-primary">Submit</button>
91-
</EditForm>
92-
93-
@code {
94-
private SfUploader UploadObj;
95-
96-
public class Employee
41+
public class UserDataModel
9742
{
98-
[Required(ErrorMessage = "Please upload a file")]
99-
public List<UploaderUploadedFiles> files { get; set; }
43+
[MinLength(1, ErrorMessage = "Please upload a file")]
44+
public List<FileInfo> files { get; set; } = new();
10045
}
10146
102-
public Employee employee = new Employee();
47+
public UserDataModel employee = new UserDataModel();
48+
private SfUploader UploaderObj;
10349
104-
public void OnSelect(SelectedEventArgs args)
50+
private async Task OnChange(UploadChangeEventArgs args, EditContext context)
10551
{
106-
this.employee.files = new List<UploaderUploadedFiles> { new UploaderUploadedFiles { Name = args.FilesData[0].Name, Type = args.FilesData[0].Type, Size = args.FilesData[0].Size } };
52+
employee.files = await UploaderObj.GetFilesDataAsync();
53+
context?.NotifyFieldChanged(FieldIdentifier.Create(() => employee.files));
10754
}
10855
109-
private async Task OnChange(UploadChangeEventArgs args)
56+
private async Task OnRemove(RemovingEventArgs args, EditContext context)
11057
{
111-
foreach (var file in args.Files)
58+
var currentFiles = await UploaderObj.GetFilesDataAsync();
59+
var fileToRemove = args.FilesData.FirstOrDefault();
60+
if (fileToRemove != null)
11261
{
113-
if (file.FileInfo != null && file.File != null)
114-
{
115-
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", file.FileInfo.Name);
116-
using FileStream filestream = new FileStream(path, FileMode.Create, FileAccess.Write);
117-
await file.File.OpenReadStream(long.MaxValue).CopyToAsync(filestream);
118-
}
62+
currentFiles = currentFiles.Where(f => f.Name != fileToRemove.Name).ToList();
11963
}
64+
employee.files = currentFiles;
65+
context?.NotifyFieldChanged(FieldIdentifier.Create(() => employee.files));
12066
}
12167
122-
public void OnRemove()
68+
public void HandleValidSubmit(EditContext args)
12369
{
124-
this.employee.files = null;
125-
}
126-
127-
public async Task HandleValidSubmit()
128-
{
129-
await this.UploadObj.UploadAsync();
70+
// The form model (args.Model) now contains the list of selected files.
71+
// The 'employee.files' property holds the FileInfo objects.
72+
// From here, you can implement custom logic to upload the files to a server,
73+
// for example, by iterating through the list and using HttpClient.
74+
var filesToUpload = employee.files;
75+
// Custom file upload logic goes here.
13076
}
13177
}
13278
```
13379

134-
{% previewsample "https://blazorplayground.syncfusion.com/embed/LNheNkBrgmbGBlgC?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}
80+
{% previewsample "https://blazorplayground.syncfusion.com/embed/rXroWjZwIzUqaemW?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}
13581

13682
![Blazor File Upload component within an EditForm, showing validation and submission.](./images/blazor-uploader-editform.gif)
13783

13884
## File Upload with DataForm Integration
13985

140-
The File Upload component can also be integrated into a Syncfusion `DataForm`, providing a streamlined way to create forms from a model. The example below shows how to save an uploaded file directly to the file system in a Blazor Server application when the form is submitted.
86+
The File Upload component can also be integrated into a Syncfusion `DataForm` to automatically build a form from a model that includes file upload capabilities.
87+
88+
When the `DataForm` is submitted, the [OnSubmit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.DataForm.SfDataForm.html#Syncfusion_Blazor_DataForm_SfDataForm_OnSubmit) event handler receives the `EditContext`. The `EditContext.Model` property contains the complete form data, including the list of `FileInfo` objects from the File Upload component. This allows you to access and process the file information as part of the form's submission logic.
14189

142-
> This file-saving approach is only compatible with Blazor Server applications.
14390

14491
```cshtml
14592
@using Syncfusion.Blazor.DataForm
14693
@using System.ComponentModel.DataAnnotations
14794
@using Syncfusion.Blazor.Inputs
148-
@using System.IO
14995
150-
<SfDataForm ID="MyForm" Model="@UserModel" Width="50%" OnSubmit="Submit">
96+
<SfDataForm ID="MyForm" Model="@UserModel" Width="50%" OnSubmit="Submit" @ref="@DataForm">
15197
<FormValidator>
15298
<DataAnnotationsValidator></DataAnnotationsValidator>
15399
</FormValidator>
154100
<FormItems>
155101
<FormItem Field="@nameof(UserModel.files)">
156102
<Template>
157-
<SfUploader @ref="UploadObj" AllowMultiple="false" AutoUpload="false" ID="UploadFiles">
158-
<UploaderEvents ValueChange="OnChange" OnRemove="OnRemove" FileSelected="OnSelect"></UploaderEvents>
103+
<SfUploader ID="UploadFiles" @ref="@UploaderObj">
104+
<UploaderEvents ValueChange="async (args) => await OnChange(args)" OnRemove="async (args) => await OnRemove(args)"></UploaderEvents>
159105
</SfUploader>
160106
</Template>
161107
</FormItem>
162108
</FormItems>
163109
</SfDataForm>
164110
165111
@code {
166-
private SfUploader UploadObj;
167-
168112
public class UserDataModel
169113
{
170-
[Required(ErrorMessage = "Please upload a file")]
171-
public List<UploaderUploadedFiles> files { get; set; }
114+
[MinLength(1, ErrorMessage = "Please upload a file")]
115+
public List<FileInfo> files { get; set; } = new();
172116
}
173117
174118
private UserDataModel UserModel = new UserDataModel();
119+
private SfDataForm DataForm;
120+
private SfUploader UploaderObj;
175121
176122
private async Task OnChange(UploadChangeEventArgs args)
177123
{
178-
foreach (var file in args.Files)
179-
{
180-
if (file.FileInfo != null && file.File != null)
181-
{
182-
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", file.FileInfo.Name);
183-
using FileStream filestream = new FileStream(path, FileMode.Create, FileAccess.Write);
184-
await file.File.OpenReadStream(long.MaxValue).CopyToAsync(filestream);
185-
}
186-
}
124+
this.UserModel.files = await UploaderObj.GetFilesDataAsync();
125+
var fieldIdentifier = FieldIdentifier.Create(() => UserModel.files);
126+
DataForm.EditContext?.NotifyFieldChanged(fieldIdentifier);
187127
}
188128
189-
private void OnRemove()
129+
private async Task OnRemove(RemovingEventArgs args)
190130
{
191-
this.UserModel.files = null;
192-
}
193-
194-
private void OnSelect(SelectedEventArgs args)
195-
{
196-
this.UserModel.files = new List<UploaderUploadedFiles> { new UploaderUploadedFiles { Name = args.FilesData[0].Name, Type = args.FilesData[0].Type, Size = args.FilesData[0].Size } };
131+
var currentFiles = await UploaderObj.GetFilesDataAsync();
132+
var fileToRemove = args.FilesData.FirstOrDefault();
133+
if (fileToRemove != null)
134+
{
135+
currentFiles = currentFiles.Where(f => f.Name != fileToRemove.Name).ToList();
136+
}
137+
this.UserModel.files = currentFiles; ;
138+
var fieldIdentifier = FieldIdentifier.Create(() => UserModel.files);
139+
DataForm.EditContext?.NotifyFieldChanged(fieldIdentifier);
197140
}
198141
199-
private async Task Submit(object args)
142+
private void Submit(EditContext args)
200143
{
201-
await this.UploadObj.UploadAsync();
144+
// The form model is available in args.Model.
145+
// The 'files' property contains the list of selected FileInfo objects.
146+
// Custom file upload logic can be implemented here.
147+
var modelWithFileData = (UserDataModel)args.Model;
148+
var filesToUpload = modelWithFileData.files;
202149
}
203150
}
204151
```
205152

206-
{% previewsample "https://blazorplayground.syncfusion.com/embed/BNBSDaBVKlbHqfgu?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}
153+
{% previewsample "https://blazorplayground.syncfusion.com/embed/LZheWNXGeJtxWIXQ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}
207154

208155
![Blazor File Upload component within a Syncfusion DataForm.](./images/blazor-uploader-dataform.gif)
-216 KB
Loading
-239 KB
Loading

0 commit comments

Comments
 (0)