如何将上传图标修复为文件上传输入(材料 UI)
Posted
技术标签:
【中文标题】如何将上传图标修复为文件上传输入(材料 UI)【英文标题】:How to fix an upload icon to a file upload input (material UI) 【发布时间】:2021-10-24 05:47:49 【问题描述】:我目前正在尝试使用 Material UI 构建一个带有图标作为输入装饰的文件上传输入字段。我希望能够点击图标上传文件。
按照此处的 MUI 文档:input adornment,我尝试遵循确切的格式,除了在演示中使用 IconButton 而不是密码可见性图标。
这是我的代码示例:
<FormControl className=classes.formControl>
<InputLabel htmlFor="upload-script">Sim Script</InputLabel>
<Input
id="upload-script"
type="file"
value=values.script
onChange=() => handleChange('script')
endAdornment=
<InputAdornment position="end">
<IconButton aria-label="upload">
<PublishIcon /> // (here is my icon)
</IconButton>
</InputAdornment>
/>
</FormControl>
这可行,但结果完全不是我想要的 - 这是它在浏览器中的截图:
您可以在右侧一直看到我的上传图标,但输入字段显然有自己的上传按钮和占位符文本('未选择文件')。
看网上,看到这里有一个建议:(similar *** post) 说我们应该在Input
组件中添加style: display: none
,并添加component="span"
作为IconButton 的属性。然而,当我尝试这个时,浏览器给我们的是这样的:
(一直滚动...我的源图标不见了,输入字段下方没有行分隔符,间距明显混乱...)
显然,这些都不是我想要的哈哈。有人可以帮忙吗?? (我希望这个描述足够好......)
非常感谢!!
-
编辑: 这是@Shiladitya 的初始解决方案的样子:
但我希望文本字段有一行!我希望它看起来与“Sim Binary”文本字段完全一样,只是右侧有一个上传图标而不是下拉箭头。
【问题讨论】:
【参考方案1】:给你一个解决方案
const handleFileUpload = () =>
<>
<input
style=
display: "none"
accept=".json" // specify the file type that you wanted to accept
id="choose-file"
type="file"
onChange=handleFileUpload
/>
<label htmlFor="choose-file">
<IconButton aria-label="upload">
<PublishIcon />
</IconButton>
</label>
</>
使用文本字段编辑
<TextField
className=classes.margin
id="input-with-icon-textfield"
label="TextField"
InputProps=
endAdornment: (
<>
<input
style=
display: "none"
accept=".json"
id="choose-file"
type="file"
onChange=handleFileUpload
/>
<label htmlFor="choose-file">
<IconButton aria-label="upload">
<PublishIcon />
</IconButton>
</label>
</>
),
/>
【讨论】:
但这只是隐藏了输入标签字段,所以你看到的只是图标。我希望图标显示在文本字段的末尾,以便用户最终可以看到选择上传的文件。 @tprebenda 请找到更新后的答案 这个更新的答案是完美的,谢谢!!【参考方案2】:另一种解决方案。
*
margin: 0 auto;
font-family: Helvetica;
html
background-color: #e9e9e9;
#choose-file
display: none;
#wrapper
display: inline-flex;
justify-content: center;
margin-left: 20px;
background-color: orange;
width: 60px;
align-items: center;
cursor: pointer;
<form>
<label id="first">
Sim Binary
<div id="wrapper">
<input
accept=".json"
id="choose-file"
type="file"
/>
⇪
</div>
</label>
</form>
【讨论】:
【参考方案3】:我最近返回并编辑了我的组件,该组件的灵感来自@Shiladitya,但现在使用了一个我以前不知何故错过的更好的系统:
<TextField
className=classes.formControl
id=`sim-script-$sim.uuid`
label="Sim Script- click the Upload Icon"
required
inputRef=scriptInputRef // To focus on the field after clicking icon
value=sim.script
InputProps=
readOnly: true,
endAdornment: (
<>
<AdjustedTooltip title="Upload script" arrow>
<IconButton
aria-label="upload"
className=classes.uploadIcon
component="label" // THIS IS THE GENIUS CHANGE
>
<PublishIcon />
<input
hidden
type="file"
onChange=(e) => scriptUpload(e)
/>
</IconButton>
</AdjustedTooltip>
</>
),
/>
这样,我们可以移除所有的输入和标签包装,而只需将 Material UI Button 设置为具有component="label"
属性,并将输入标签放在图标按钮内。
这也是我的 onChange/scriptUpload 函数,以防人们感兴趣:
const scriptUpload = (e: ChangeEvent<HTMLInputElement>) =>
// the first/only file selected by user
if (e.target.files?.item(0))
onChange(sim.uuid, "script", e.target.files?.item(0)!.name);
// Focus textfield
if (scriptInputRef.current)
scriptInputRef.current.focus();
;
【讨论】:
以上是关于如何将上传图标修复为文件上传输入(材料 UI)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 REST API 将文件和附件上传到 sobject 记录?