[英]Ηow can I get the filename of a file uploaded with a shiny fileInput?
[英]R shiny restrict fileInput to filename pattern and not just file type
我有一個 Shiny 應用程序,它使用fileInput
在客戶端獲取一些文件(我不能使用在服務器端管理文件的 shinyFiles package)。
我希望用戶只能上傳與特定模式匹配的文件(例如helloWorld.txt
),而不僅僅是匹配文件類型(例如文本、csv 等)。
fileInput
有一個accept
參數,您可以在其中提供接受的文件類型。 從文檔:
accept A character vector of MIME types; gives the browser a hint of
what kind of files the server is expecting.
我不只是想指定接受的文件類型,這對我的應用程序來說不夠嚴格。 有沒有辦法做到這一點?
這是一個只接受文本文件的 MWE:
library(shiny)
ui <- fluidPage(
fileInput(
"file_choice",
label = "Choose a files",
multiple = TRUE,
accept = c(
".txt"
)
)
)
server <- function(input, output, session) {}
shinyApp(ui, server)
如果我使用:
accept = c(
"helloWorld.txt"
)
它不起作用,因為它不是 MIME 類型。
此頁面Shiny 文件輸入參數“接受”問題建議在服務器端之后處理所選文件,這是我最終要做的,但我更喜歡先驗限制而不是后驗限制(以避免服務器端文件檢查並反饋給用戶)。
一種方法是插入一些 javascript 作為onchange
事件觸發器,檢查文件名,如果不匹配,則中斷上傳過程。 這種方法使用alert
,我知道很多人認為這種方法有點侵入性並且不美觀,我相信其他人可以提出更好的建議。
我應該從一個簡單的警告開始:這里的條件嚴格來說是“文件名以文字hello
開頭” 。 您的示例可能需要更多技巧,而不是需要文件名 sans-extension 匹配。 在這種情況下,可能需要正則表達式,請參考https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 之類的內容以獲取更多信息。 這個答案提供的是一個框架供您填補漏洞。
(在修改此代碼時,您可能會發現添加alert(FileName)
和/或alert(FileBase)
以查看 javascript 與您的模式進行比較很有用。每次嘗試都會彈出。在我的例子中,它幫助我發現毫不奇怪,存在 windows 路徑,這意味着它使用反斜杠而不是正斜杠,需要split(/[\\/]/)
,進一步轉義為 R。)
checkjs <- 'function checkFileName(fieldObj) {
var FileName = fieldObj.value;
var FileBase = FileName.split(/[\\\\/]/).pop();
if (! FileBase.startsWith("hello")) {
fieldObj.value = "";
alert("File does not start with hello");
return false;
}
return true;
}'
attrib_replace <- function(x, cond, ...) {
if (all(names(cond) %in% names(x)) && identical(cond, x[names(cond)])) x <- c(x, list(...))
if ("attribs" %in% names(x)) x$attribs <- attrib_replace(x$attribs, cond = cond, ...)
if ("children" %in% names(x)) x$children <- lapply(x$children, function(ch) attrib_replace(ch, cond = cond, ...))
x
}
一個示例應用程序,使用它:
library(shiny)
shinyApp(
ui = fluidPage(
tags$script(checkjs),
attrib_replace(fileInput(
"file_choice",
label = "Choose a file",
multiple = TRUE,
accept = c(".txt")
), list(id = "file_choice", type = "file"), onchange = "checkFileName(this);")
),
server = function(input, output, session) {}
)
當您 select 文件不以“hello”開頭時,它會發出警報並且不會上傳文件。 正確的文件只上傳文件。
我為此引用的其他一些答案:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.