簡體   English   中英

R shiny 將文件輸入限制為文件名模式,而不僅僅是文件類型

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM