mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-12-02 03:59:14 +08:00
!852 feat(#I2C63D): add ClickToUpload mode in Upload component
* docs: 增加点击上传模式示例文件 * docs: 增加点击上传示例文档 * feat: 增加点击上传功能 * chore: 打包脚本不输出颜色 * feat: 增加单击上传模式 * chore: 增加 bundle&minifier Cli tool * docs: 更新 Upload 示例文件 * docs: 更新 Table 示例文件 * style: upload 适配移动端
This commit is contained in:
parent
e97d8eff21
commit
841d83b2fa
@ -11,20 +11,19 @@
|
||||
<DetailRowTemplate>
|
||||
<Tab>
|
||||
<TabItem Text="明细数据">
|
||||
@{
|
||||
// 此段代码为提高性能
|
||||
var cacheKey = context.Name ?? "";
|
||||
var DetailDataSource = Enumerable.Empty<DetailRow>
|
||||
();
|
||||
if (Cache.ContainsKey(cacheKey))
|
||||
{
|
||||
DetailDataSource = Cache[cacheKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailDataSource = GetDetailRowsByName(cacheKey).ToList();
|
||||
Cache.Add(cacheKey, DetailDataSource);
|
||||
}
|
||||
@{
|
||||
// 此段代码为提高性能
|
||||
var cacheKey = context.Name ?? "";
|
||||
var DetailDataSource = Enumerable.Empty<DetailRow>();
|
||||
if (Cache.ContainsKey(cacheKey))
|
||||
{
|
||||
DetailDataSource = Cache[cacheKey];
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailDataSource = GetDetailRowsByName(cacheKey).ToList();
|
||||
Cache.Add(cacheKey, DetailDataSource);
|
||||
}
|
||||
}
|
||||
<Table TItem="DetailRow" IsBordered="true" ShowToolbar="false" Items="@DetailDataSource">
|
||||
<TableColumns Context="Detail">
|
||||
|
@ -1 +1,15 @@
|
||||
<Upload />
|
||||
<Upload ShowDeleteButton="true" OnChange="@OnFileChange" OnDelete="@OnFileDelete"></Upload>
|
||||
|
||||
@code {
|
||||
private Task<string> OnFileChange(InputFileChangeEventArgs args)
|
||||
{
|
||||
Trace?.Log($"{args.File.Name} 上传成功");
|
||||
return Task.FromResult("");
|
||||
}
|
||||
|
||||
private Task<bool> OnFileDelete(string fileName)
|
||||
{
|
||||
Trace?.Log($"{fileName} 成功移除");
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
<Upload ShowPreview="true"></Upload>
|
||||
<Upload Style="UploadStyle.ClickToUpload" OnDelete="@(fileName => Task.FromResult(true))"></Upload>
|
||||
|
@ -1 +1,15 @@
|
||||
<Upload IsCircle="true"></Upload>
|
||||
@{
|
||||
var DefaultFileList = new List<UploadFile>();
|
||||
DefaultFileList.AddRange(new[]
|
||||
{
|
||||
new UploadFile()
|
||||
{
|
||||
FileName = "default1.jpg"
|
||||
},
|
||||
new UploadFile()
|
||||
{
|
||||
FileName = "default2.jpg"
|
||||
}
|
||||
});
|
||||
}
|
||||
<Upload Style="UploadStyle.ClickToUpload" OnDelete="@(fileName => Task.FromResult(true))" DefaultFileList="@DefaultFileList"></Upload>
|
||||
|
@ -4,15 +4,6 @@
|
||||
|
||||
<h4>通过点击或者拖拽上传文件</h4>
|
||||
|
||||
<p>
|
||||
由于上传组件上传文件的大小受后台程序、反向代理等诸多因素影响,相关文章请参阅 <a href="https://gitee.com/LongbowEnterprise/BootstrapBlazor/wikis/Upload%20%E7%BB%84%E4%BB%B6%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A1%B9?sort_id=2166580" target="_blank">Upload 组件注意事项</a>
|
||||
<br>出于服务器安全考虑,以下组件示例中上传文件均限制为文件类型必须为 <code>image/*</code> ,文件大小被限制为不能超过 <code>20 MB</code>
|
||||
</p>
|
||||
|
||||
<Tips>
|
||||
<p>本组件正在开发中,此页面为测试功能时使用</p>
|
||||
</Tips>
|
||||
|
||||
<Block Title="基本用法" Introduction="与其他表单组件一起使用,显示文件名称,点击 <b>浏览</b> 按钮后选择文件并上传;通过设置 <code>ShowRemoveButton</code> 参数,显示 <b>删除</b> 按钮,点击删除按钮时回调 <code>OnDelete</code> 委托方法" CodeFile="upload.1.html">
|
||||
<div class="form-inline">
|
||||
<div class="row">
|
||||
@ -33,6 +24,35 @@
|
||||
<Logger @ref="Trace" />
|
||||
</Block>
|
||||
|
||||
<Block Title="点击上传" Introduction="经典款式,用户点击按钮弹出文件选择框。" CodeFile="upload.2.html">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6">
|
||||
<Upload Style="UploadStyle.ClickToUpload" OnDelete="@(fileName => Task.FromResult(true))"></Upload>
|
||||
</div>
|
||||
</div>
|
||||
</Block>
|
||||
|
||||
<Block Title="已上传文件列表" Introduction="使用 <code>DefaultFileList</code> 设置已上传的内容" CodeFile="upload.3.html">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-6">
|
||||
@{
|
||||
var DefaultFileList = new List<UploadFile>();
|
||||
DefaultFileList.AddRange(new[]
|
||||
{
|
||||
new UploadFile()
|
||||
{
|
||||
FileName = "default1.jpg"
|
||||
},
|
||||
new UploadFile()
|
||||
{
|
||||
FileName = "default2.jpg"
|
||||
}
|
||||
});
|
||||
}
|
||||
<Upload Style="UploadStyle.ClickToUpload" OnDelete="@(fileName => Task.FromResult(true))" DefaultFileList="@DefaultFileList"></Upload>
|
||||
</div>
|
||||
</div>
|
||||
</Block>
|
||||
<!--<Block Title="预览后上传" Introduction="通过设置 <code>ShowPreview</code> 属性开启本地预览,点击上传按钮开始上传" CodeFile="upload.2.html">
|
||||
<p>仅允许上传 <code>images/*</code> 格式文件,文件大小不能超过 <code>20 MB</code></p>
|
||||
<Upload AllowFileType="@AllowFiles" MaxFileLength="20971520" ShowPreview="true" OnUploaded="@OnPreviewUpload"></Upload>
|
||||
|
@ -5,16 +5,32 @@
|
||||
@if (Style == UploadStyle.Normal)
|
||||
{
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" id="@Id" readonly placeholder="@PlaceHolder" value="@FileName" />
|
||||
<input type="text" class="form-control" id="@Id" readonly placeholder="@PlaceHolder" value="@(UploadFiles.FirstOrDefault()?.FileName)" />
|
||||
<div class="input-group-append">
|
||||
@if (ShowDeleteButton)
|
||||
{
|
||||
<Button class="@RemoveButtonClassString" IsDisabled="@IsDeleteButtonDisabled" Icon="@DeleteButtonIcon" Text="@DeleteButtonText" OnClick="@OnFileDelete" />
|
||||
<Button class="@RemoveButtonClassString" IsDisabled="@IsDeleteButtonDisabled" Icon="@DeleteButtonIcon" Text="@DeleteButtonText" OnClick="@(e => OnFileDelete(UploadFiles.FirstOrDefault()))" />
|
||||
}
|
||||
@*<Button class="@UploadButtonClassString" IsDisabled="@IsDisabled" Icon="@UploadButtonIcon" Text="@UploadButtonText" />*@
|
||||
<Button class="@BrowserButtonClassString" IsDisabled="@IsDisabled" Icon="@BrowserButtonIcon" Text="@BrowserButtonText" OnClick="@OnFileBrowser" />
|
||||
</div>
|
||||
</div>
|
||||
<InputFile hidden accept="@AllowFileType" OnChange="OnFileChange" />
|
||||
}
|
||||
else if (Style == UploadStyle.ClickToUpload)
|
||||
{
|
||||
<Button class="@BrowserButtonClassString" IsDisabled="@IsDisabled" Icon="@BrowserButtonIcon" Text="@BrowserButtonText" />
|
||||
<div class="upload-body">
|
||||
@foreach (var item in UploadFiles)
|
||||
{
|
||||
<div class="@GetUploadItemClassString(item)">
|
||||
<i class="@GetFileIcon(item)"></i>
|
||||
<span>@item.FileName</span>
|
||||
<i class="fa fa-check-circle-o text-success"></i>
|
||||
<i class="fa fa-trash-o text-danger" @onclick:stopPropagation @onclick="@(e => OnFileDelete(item))"></i>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<InputFile hidden multiple="@MultipleString" accept="@AllowFileType" OnChange="OnFileChange" />
|
||||
}
|
||||
@*<div class="upload-item">
|
||||
<div class="@PreviewClassString" style="@PrevStyleString">
|
||||
@ -35,5 +51,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>*@
|
||||
<InputFile hidden multiple="@MultipleString" accept="@AllowFileType" OnChange="OnFileChange" />
|
||||
</div>
|
||||
|
@ -11,6 +11,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BootstrapBlazor.Components
|
||||
@ -57,6 +58,15 @@ namespace BootstrapBlazor.Components
|
||||
.AddClass($"height: {Width}px;", !IsStack && IsCircle)
|
||||
.Build();
|
||||
|
||||
private string? GetUploadItemClassString(UploadFile item) => CssBuilder.Default("upload-item")
|
||||
.AddClass("is-valid", item.Code == 0)
|
||||
.AddClass("is-invalid", item.Code != 0)
|
||||
.Build();
|
||||
|
||||
private string? GetFileIcon(UploadFile item) => CssBuilder.Default("fa")
|
||||
.AddClass("fa-file-text-o", true)
|
||||
.Build();
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 圆形进度半径
|
||||
/// </summary>
|
||||
@ -94,7 +104,10 @@ namespace BootstrapBlazor.Components
|
||||
.AddClass(BrowserButtonClass)
|
||||
.Build();
|
||||
|
||||
private bool IsDeleteButtonDisabled => IsDisabled || string.IsNullOrEmpty(FileName);
|
||||
private bool IsDeleteButtonDisabled => IsDisabled || !UploadFiles.Any();
|
||||
|
||||
[NotNull]
|
||||
private List<UploadFile>? UploadFiles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 上传组件模式 默认为 Normal 正常模式多用于表单中
|
||||
@ -157,10 +170,11 @@ namespace BootstrapBlazor.Components
|
||||
public string Icon { get; set; } = "fa fa-cloud-upload";
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 上传文件名
|
||||
/// 获得/设置 已上传文件集合
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public string? FileName { get; set; }
|
||||
[NotNull]
|
||||
public List<UploadFile>? DefaultFileList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否显示预览 默认不预览
|
||||
@ -306,6 +320,15 @@ namespace BootstrapBlazor.Components
|
||||
ResetText ??= Localizer[nameof(ResetText)];
|
||||
FileTooLargeText ??= Localizer[nameof(FileTooLargeText)];
|
||||
AllowFileTypeErrorMessage ??= Localizer[nameof(AllowFileTypeErrorMessage)];
|
||||
|
||||
if (Style != UploadStyle.Normal)
|
||||
{
|
||||
UploadFiles ??= new List<UploadFile>();
|
||||
}
|
||||
|
||||
UploadFiles ??= new List<UploadFile>();
|
||||
|
||||
if (DefaultFileList != null) UploadFiles.AddRange(DefaultFileList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -322,42 +345,45 @@ namespace BootstrapBlazor.Components
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnFileDelete()
|
||||
private async Task OnFileDelete(UploadFile? item)
|
||||
{
|
||||
if (OnDelete != null && !string.IsNullOrEmpty(FileName))
|
||||
if (OnDelete != null && item != null)
|
||||
{
|
||||
var ret = await OnDelete(FileName);
|
||||
var ret = await OnDelete(item.File?.Name ?? item.FileName);
|
||||
if (ret)
|
||||
{
|
||||
FileName = null;
|
||||
UploadFiles.Remove(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Task OnFileBrowser()
|
||||
{
|
||||
FileName = "";
|
||||
// 单文件模式
|
||||
UploadFiles.Clear();
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task OnFileChange(InputFileChangeEventArgs args)
|
||||
{
|
||||
FileName = args.File.Name;
|
||||
|
||||
if (OnChange == null)
|
||||
var file = new UploadFile()
|
||||
{
|
||||
var format = args.File.ContentType;
|
||||
var imageFile = await args.File.RequestImageFileAsync(format, 640, 480);
|
||||
FileName = args.File.Name,
|
||||
Size = args.File.Size,
|
||||
File = args.File
|
||||
};
|
||||
UploadFiles.Add(file);
|
||||
|
||||
using var fileStream = imageFile.OpenReadStream();
|
||||
using var memoryStream = new MemoryStream();
|
||||
await fileStream.CopyToAsync(memoryStream);
|
||||
|
||||
ImageUrl = $"data:{format};base64,{Convert.ToBase64String(memoryStream.ToArray())}";
|
||||
if (Style == UploadStyle.Normal)
|
||||
{
|
||||
if (OnChange != null)
|
||||
{
|
||||
ImageUrl = await OnChange(args);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (Style == UploadStyle.ClickToUpload)
|
||||
{
|
||||
ImageUrl = await OnChange(args);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
|
||||
namespace BootstrapBlazor.Components
|
||||
{
|
||||
/// <summary>
|
||||
@ -38,5 +40,10 @@ namespace BootstrapBlazor.Components
|
||||
/// 获得/设置 错误信息
|
||||
/// </summary>
|
||||
public string? Error { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 上传文件实例
|
||||
/// </summary>
|
||||
internal IBrowserFile? File { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,6 @@
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
// Website: https://www.blazor.zone or https://argozhang.github.io/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BootstrapBlazor.Components
|
||||
{
|
||||
/// <summary>
|
||||
@ -18,8 +12,11 @@ namespace BootstrapBlazor.Components
|
||||
/// <summary>
|
||||
/// 正常模式
|
||||
/// </summary>
|
||||
Normal
|
||||
|
||||
Normal,
|
||||
|
||||
/// <summary>
|
||||
/// 点击上传
|
||||
/// </summary>
|
||||
ClickToUpload,
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -3640,9 +3640,52 @@ input:disabled,
|
||||
/*end calendar*/
|
||||
|
||||
/*upload*/
|
||||
.form-inline .upload {
|
||||
width: calc(100% - 104px);
|
||||
@media (min-width: 576px) {
|
||||
.form-inline .upload {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.form-inline .upload {
|
||||
width: calc(100% - 104px);
|
||||
}
|
||||
}
|
||||
|
||||
.upload .upload-body {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 3px 5px;
|
||||
border-radius: 3px;
|
||||
transition: background-color .3s linear;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item:not(:last-child) {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item:hover {
|
||||
background-color: #ebeef5;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item:hover .fa-trash-o {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item span {
|
||||
flex: 1;
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
.upload .upload-body .upload-item .fa-trash-o,
|
||||
.upload .upload-body .upload-item:hover .fa-check-circle-o {
|
||||
display: none;
|
||||
}
|
||||
/*end upload*/
|
||||
|
||||
/*divider*/
|
||||
|
File diff suppressed because one or more lines are too long
@ -43,4 +43,4 @@ var QRCode;!function(){function a(a){this.mode=c.MODE_8BIT_BYTE,this.data=a,this
|
||||
$file.trigger('click');
|
||||
});
|
||||
};
|
||||
})(jQuery);
|
||||
})(jQuery);
|
||||
|
Loading…
Reference in New Issue
Block a user