Skip to content
Merged
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
104 changes: 50 additions & 54 deletions blazor/file-upload/template.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,69 @@
---
layout: post
title: Template in Blazor File Upload Component | Syncfusion
description: Checkout and learn here about Template in Syncfusion Blazor File Upload component and much more details.
description: Learn how to customize the Syncfusion Blazor File Upload component's appearance using templates, including how to add a progress bar.
platform: Blazor
control: File Upload
documentation: ug
---

# Template in Blazor File Upload Component

The template feature customizes how each file item is rendered in the uploader UI. It enables full control over layout and styling for file details such as name, size, and status, so the interface can match application design requirements and provide a tailored user experience.
The Blazor File Upload component allows for the customization of the file list items by using a template. This provides the flexibility to define the structure and styling of individual file elements, such as the file name, size, and status. A custom template can create a tailored and visually appealing file upload interface that aligns with an application's design and user experience requirements.

### With server-side API endpoint

Use a template with server endpoints when uploads are processed by a backend. The template controls only the display of file items; the upload flow still uses SaveUrl and RemoveUrl.

```cshtml
@using Syncfusion.Blazor.Inputs

<SfUploader ID="Files" AutoUpload="false">
<UploaderAsyncSettings SaveUrl="https://blazor.syncfusion.com/services/production/api/FileUploader/Save"
RemoveUrl="https://blazor.syncfusion.com/services/production/api/FileUploader/Remove"></UploaderAsyncSettings>
<UploaderTemplates>
<Template>
<div class="name file-name" title="@(context.Name)">File Name : @(context.Name)</div>
<div class="file-size">File Size : @(context.Size)</div>
<div class="e-file-status">File Status : @(context.Status)</div>
<Template Context="context">
<div style="padding: 10px;">
<div class="name file-name" title="@context.Name">File Name : @context.Name</div>
<div class="file-size">File Size : @context.Size</div>
<div class="e-file-status">File Status : @context.Status</div>
</div>
</Template>
</UploaderTemplates>
</SfUploader>
```
### Without server-side API endpoint

Use a template without server endpoints when handling files locally (for example, demos or trusted environments). The template syntax and available context properties are the same as the server-backed example.

```cshtml
@using Syncfusion.Blazor.Inputs

<SfUploader ID="Files" AutoUpload="false">
<UploaderTemplates>
<Template>
<div class="name file-name" title="@(context.Name)">File Name : @(context.Name)</div>
<div class="file-size">File Size : @(context.Size)</div>
<div class="e-file-status">File Status : @(context.Status)</div>
<Template Context="context">
<div style="padding: 10px;">
<div class="name file-name" title="@context.Name">File Name : @context.Name</div>
<div class="file-size">File Size : @context.Size</div>
<div class="e-file-status">File Status : @context.Status</div>
</div>
</Template>
</UploaderTemplates>
</SfUploader>
```

### Adding progressbar using template
{% previewsample "https://blazorplayground.syncfusion.com/embed/rZrSZOLhhmAhbeZR?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}

## Adding a progress bar using a template

When using a custom file template, the built-in progress bar is not shown. The following example disables the default progress indicator (ShowProgressBar=false), renders a custom progress element in the template, and updates it during stream read/write in the ValueChange event. The template displays file name, size, progress, and status, and toggles remove/delete icons based on item state. In browser-only environments (such as WebAssembly), write streams to appropriate storage or a server API; writing directly to the local file system is supported in server/desktop contexts.
When using a file upload template, the default progress bar is not displayed in the UI. A progress bar can be added within the template, and its progress can be updated by reading and writing to the stream in the `ValueChange` event. The following code snippet demonstrates how to add a progress bar to a Blazor File Upload component using a custom template. The custom template includes elements to display the file name, size, progress bar, and file status.

```cshtml
@using Syncfusion.Blazor.Inputs
@using Syncfusion.Blazor.ProgressBar
<SfUploader @ref="@uploderObj" ID="UploadFiles" MaxFileSize="100000000000" ShowProgressBar = "false">
<UploaderEvents BeforeUpload="onBeforeUpload" Success="onSuccess" ValueChange="onChange"></UploaderEvents>

<SfUploader @ref="@uploaderObj" ID="UploadFiles" MaxFileSize="100000000000" ShowProgressBar="false">
<UploaderEvents BeforeUpload="OnBeforeUpload" Success="OnSuccess" ValueChange="OnChange"></UploaderEvents>
<UploaderTemplates>
<Template>
<Template Context="context">
<span class="e-file-container">
<span class="e-file-name" title="@(context.Name)">@this.GetFileName(context.Name)</span>
<span class="e-file-name" title="@context.Name">@GetFileName(context.Name)</span>
<span class="e-file-type">@("." + context.Type)</span>
@if (context.Size > 0)
{
Expand All @@ -71,9 +74,9 @@ When using a custom file template, the built-in progress bar is not shown. The f
{
<span class="e-upload-progress-wrap">
<span class="e-progress-inner-wrap">
<progressbar class="@("e-upload-progress-bar" + " " + "e-upload-progress")" value="0" max="100" style="width: @(ProgressValue.ToString() + "%")"></progressbar>
<progress class="@("e-upload-progress-bar" + " " + "e-upload-progress")" value="0" max="100" style="width: @(ProgressValue + "%")"></progress>
</span>
<span class="e-progress-bar-text">@(ProgressValue.ToString() + "%")</span>
<span class="e-progress-bar-text">@(ProgressValue + "%")</span>
</span>
}
@if (fileStates.ContainsKey(context.Name) && fileStates[context.Name] && context.Status == "File uploaded successfully")
Expand All @@ -90,112 +93,103 @@ When using a custom file template, the built-in progress bar is not shown. The f
}
@if (fileStates.ContainsKey(context.Name) && fileStates[context.Name] && context.Status == "File uploaded successfully")
{
<span class="e-icons e-file-delete-btn @this.RemoveIconDisable" id="deleteIcon" title="Delete" @onclick="(args) => ClickHandler(context)"></span>
<span class="e-icons e-file-delete-btn @RemoveIconDisable" id="deleteIcon" title="Delete" @onclick="(args) => ClickHandler(context)"></span>
}
else
{
<span class="e-icons e-file-remove-btn @this.RemoveIconDisable" id="removeIcon" title="Remove" @onclick="(args) => ClickHandler(context)"></span>
<span class="e-icons e-file-remove-btn @RemoveIconDisable" id="removeIcon" title="Remove" @onclick="(args) => ClickHandler(context)"></span>
}
</span>

</Template>
</UploaderTemplates>
</SfUploader>

@code {
private SfUploader uploderObj;
public bool isVisible { get; set; } = false;
private FileInfo CurrentFile {get; set;}
private SfUploader uploaderObj;
private FileInfo CurrentFile { get; set; }
public string fileSize { get; set; } = "0";
public string RemoveIconDisable = string.Empty;
#pragma warning disable CA2213 // Disposable fields should be disposed
private readonly SemaphoreSlim FileSemaphore = new SemaphoreSlim(1);
#pragma warning restore CA2213 // Disposable fields should be disposed
private decimal ProgressValue { get; set; } = 0;
private Dictionary<string, bool> fileStates = new Dictionary<string, bool>();

public string CalculateFileSize(double size)
{
string fileSizeStr = "";
if (size >= 1024 * 1024)
{
return fileSizeStr = $"{size / (1024f * 1024f):0.00} MB";
return $"{size / (1024f * 1024f):0.00} MB";
}
else if (size >= 1024)
{
return fileSizeStr = $"{size / 1024f:0.00} KB";
return $"{size / 1024f:0.00} KB";
}
else
{
return fileSizeStr = $"{size} bytes";
return $"{size} bytes";
}
}

private string GetFileName(string fileName)
{
string type = GetFileType(fileName);
string[] names = fileName.Split(new string[] { "." + type }, StringSplitOptions.None);
return names[0];
}

private string GetFileType(string name)
#pragma warning restore CA1822 // Mark members as static
{
string extension = string.Empty;
int index = name.LastIndexOf('.');
if (index > 0)
{
extension = name.Substring(index + 1);
}

return (!string.IsNullOrEmpty(extension)) ? extension : string.Empty;
}
private async Task onFileRemove()
{
await uploderObj.RemoveAsync();
return !string.IsNullOrEmpty(extension) ? extension : string.Empty;
}

public async Task ClickHandler(FileInfo context)
{
await uploderObj.RemoveAsync(new FileInfo[] { context });
await uploaderObj.RemoveAsync(new FileInfo[] { context });
}
public void onBeforeUpload(BeforeUploadEventArgs args)

public void OnBeforeUpload(BeforeUploadEventArgs args)
{
foreach (var file in args.FilesData)
{
fileStates[file.Name] = false;
}
}
public void onSuccess(SuccessEventArgs args)

public void OnSuccess(SuccessEventArgs args)
{
//fileStates[args.File.Name] = false;
isVisible = false;
this.ProgressValue = 0;
ProgressValue = 0;
}
public async Task onChange(UploadChangeEventArgs args)

public async Task OnChange(UploadChangeEventArgs args)
{
await FileSemaphore.WaitAsync();
try
{
foreach (var file in args.Files)
{
var path = @"" + file.FileInfo.Name;
var path = Path.Combine(Path.GetTempPath(), file.FileInfo.Name);
CurrentFile = file.FileInfo;
CurrentFile.Status = "Uploading";
await using FileStream writeStream = new(path, FileMode.Create);
using var readStream = file.File.OpenReadStream(file.File.Size);
var bytesRead = 0;
var totalRead = 0;
var buffer = new byte[1024 * 10];

while ((bytesRead = await readStream.ReadAsync(buffer)) != 0)
{
RemoveIconDisable = "e-disabled";
totalRead += bytesRead;
await writeStream.WriteAsync(buffer, 0, bytesRead);
ProgressValue = (long)((decimal)readStream.Position * 100) / readStream.Length;
StateHasChanged();
}
CurrentFile.Status = "File uploaded successfully";
RemoveIconDisable = string.Empty;
fileStates[file.FileInfo.Name] = true;

}
}
catch (Exception ex)
Expand All @@ -211,4 +205,6 @@ When using a custom file template, the built-in progress bar is not shown. The f
}
```

![Blazor FileUpload with Chunk Upload](./images/blazor-template-progressbar.gif)
{% previewsample "https://blazorplayground.syncfusion.com/embed/LNLytYhhLmmEGpkj?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %}

![Blazor File Upload with a custom template and progress bar](./images/blazor-template-progressbar.gif)