R拖放上的闪亮输入反应错误 [英] R Shiny Input Reactivity Error on Drag-and-Drop

查看:79
本文介绍了R拖放上的闪亮输入反应错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用一些自定义js创建R Shiny应用,以提供拖放功能。虽然拖放操作对于单个文件非常有效,但是当我使用ShinyJS重置它时,再次上传相同文件无法正常工作。我了解这是因为onchange函数不会在重新输入相同名称的文件时触发(无论文件内容是否已修改)

Im currently creating a R Shiny app with some custom js to provide drag and drop functionality. While the drag and drop works perfectly for a single file, when I reset it using shinyJS, uploading the same file again does not work properly. I understand that this is because the onchange function is not being triggerred with the file with the same name being re-inputted (regardless of if the file contents have been modified)

JS:

var datasets = {};
var dragOver = function(e) { e.preventDefault(); };

var dropData = function(e) {
    e.preventDefault();
    handleDrop(e.dataTransfer.files);
};

var removeFiles = function(e){
    jQuery('#datafile').empty();
}

var handleDrop = function(files) {
    for (var i = 0, f; f = files[i]; i++) {
    var reader = new FileReader();

    reader.onload = (function(file) {
        return function(e) {
        datasets[file.name.toLowerCase()] = e.target.result;
        Shiny.onInputChange("datafile", datasets);
        var div = document.createElement("div");
        var src = "https://cdn0.iconfinder.com/data/icons/office/512/e42-512.png";
        div.id = "datasets";
        div.innerHTML = [
            "<img class='thumb' src='", src, "' title='", encodeURI(file.name),
            "'/>", "<br>", file.name, "<br>"].join('');
        document.getElementById("drop-area").appendChild(div);
        };
    })(f);
    reader.readAsText(f);
    }
};

Server.R(部分用于查看文件输入):

Server.R (The part of it looking at file input):

observeEvent(input$datafile, {
    infile <- input$datafile
    if (is.null(infile)) {
      # User has not uploaded a file yet
      return(NULL)
    }

    # CLEAN FILE
    name <- names(input$datafile)[1]
    csvFile <- read.csv(text=input$datafile[[name]])

  output$dataTable <- renderDataTable(csvFile , options = list(scrollX = '1100px') )

}

ui .R(只是相关部分):

ui.R (Just the relevant portion):

   # DRAG AND DROP FILE INPUT
   h3(id="data-title", "Drop Datasets"),

   div(class="col-xs-12", id="drop-area", ondragover="dragOver(event)", 
       ondrop="dropData(event)" , onClick="fallback(event)"),

   div(onClick="removeFiles(event)", actionButton(inputId="resetAutomaticInput", label="Reset Input")

我不知道如何使闪亮的值具有反应性,以触发与input $ datafile相关的事件。

I do not understand how to make my shiny values reactive to trigger the event associated with input$datafile. Any help is deeply appreciated!

推荐答案

我对此进行了研究并使用了一段时间,使其成为一个有效的示例。第一。我认为拖放功能是一个有用的示例。它也正确处理多点。也有一些有趣的javascript构造-至少对我来说。

I had a look at this and played with it for awhile, making it into a working example first. I think the drag-and-drop functionality is a useful example here. It handles multi-drop correctly too. There are some interesting javascript constructs in it too - at least to me.

为了解决这个问题,我没有使用BigDataScientist建议的随机数,而是使用了一个对其他事物也可能有用的计数。

To fix the problem, instead of a random number like BigDataScientist suggested, I just used a count which could be useful for other things too.

总共进行了以下更改:


  • 将这些片段完整地整理成一个完整的Shiny工作示例并将其保存到

  • 将javascript代码放入保存了Shiny代码的目录下的名为 www 的子目录中。
  • li>
  • 在UI代码中添加了 tag $ head(tag $ script(... 语句以加载该javascript。)

  • 放置区域 div 中添加了一些innerhtml文本,因此可以将其放入。

  • 在javascript中添加了 dropcount

  • 更改了html,以使 dropcount 将回显到放置区域 div。

  • 更改了输出到 verbatumPrintOutput ,以便您可以在

  • 在输出中添加了更多字段,因此您可以更好地看到 input $ datafile 中的内容。

  • 将JS for 循环更改为不会产生警告的内容。

  • 添加了 jslint 在顶部进行注释以消除其他警告。

  • 添加了一些输出字段( inputdatafile rowsdatafile ),因此您可以跟踪 input $ datafile 中的内容-直到我不清楚为止真正的错误是什么,但这只是我...

  • 稍微改变了输出中的逻辑,以使重置功能按人们可能期望的方式工作(示例代码似乎仍然不完整)

  • 可能我忘了其他一些小东西。

  • Completed the fragments into a complete Shiny working example and saved it to its own directory.
  • Placed the javascript code into a sub-directory named www under the directory the Shiny code was saved.
  • Added a tag$head(tag$script(... statement in the UI code to load that javascript.
  • Added some innerhtml text to the drop-area div so there is something to drop it into.
  • Added a dropcount to the javascript.
  • Changed the html so that that dropcount would be echoed to the drop-area div.
  • Changed the output to verbatumPrintOutput so you can see more of the dataframe in less area.
  • Added a couple more fields to the output so you could see better what was in input$datafile.
  • Changed the JS for loop to something that would not generate a warning.
  • Added a jslint comment up top to get rid of another warning.
  • Added some output fields (inputdatafile and rowsdatafile) so you could track what was in input$datafile - until I did that I was not clear what the real error was, but that is just me...
  • Changed the logic slightly in the output to make the reset functionality work the way one would probably expect (the example code seemed still incomplete)
  • Probably a few other small things that I forgot.

这是代码:

JS:

/*jshint loopfunc:true */ // git rid of warning
var datasets = {};
var dragOver = function(e) { e.preventDefault(); };

var dropData = function(e) {
  e.preventDefault();
  handleDrop(e.dataTransfer.files);
};
var dropcount=0;

var removeFiles = function(e){
    txt = "Drop Area "+dropcount;
    jQuery('#drop-area').html(txt);
    datasets = {};
    Shiny.onInputChange("datafile", datasets);
};
var handleDrop = function(files) {
  for (var i = 0; i<files.length; i++) {
    f = files[i];
    var reader = new FileReader();

    reader.onload = (function(file) {
      return function(e) {
        datasets[file.name.toLowerCase()+'|'+dropcount] = e.target.result;
        Shiny.onInputChange("datafile", datasets);
        var div = document.createElement("div");
        var src = "https://cdn0.iconfinder.com/data/icons/office/512/e42-512.png";
        div.id = "datasets";
        div.innerHTML = [
          "<img class='thumb' src='", src, "' title='", encodeURI(file.name),
          "'/>", "<br>", file.name, "<br>"].join('');
        drpel = document.getElementById("drop-area");
        drpel.appendChild(div);
        drpel.childNodes[0] = "Drop Area "+dropcount;
      };
    })(f);
    reader.readAsText(f);
    dropcount++;
  }
};

这是闪亮的东西:

library(plotly)
library(htmlwidgets)
library(shiny)
library(ggplot2)

ui <- shinyUI(fluidPage(

  tags$head(tags$script(type="text/javascript", src = "fileUp.js")),

  # DRAG AND DROP FILE INPUT
  h3(id="data-title", "Drop Datasets"),

  div(class="col-xs-12",id="drop-area",ondragover="dragOver(event)", 
      ondrop="dropData(event)",onClick="fallback(event)","Drop Area"),

  div(onClick="removeFiles(event)",
      actionButton(inputId="resetAutomaticInput",label="Reset Input"),
      verbatimTextOutput("inputdatafile"),
      verbatimTextOutput("rowsdatafile"),
      verbatimTextOutput("dataTable"))
))    
server <- shinyServer(function(input, output) {

  observeEvent(input$datafile, {
    infile <- input$datafile
    if (length(infile)==0) {
      # User has not uploaded a file yet
        return(NULL)
    }    
    # CLEAN FILE
    name <- names(input$datafile)[length(infile)]
    csvFile <- reactive(
      if (length(input$datafile)>0){
        read.csv(text=input$datafile[[name]])
      }
    )

    output$dataTable <- renderPrint(csvFile())
    output$inputdatafile <- renderPrint(names(input$datafile))
    output$rowsdatafile <- renderPrint(sapply(input$datafile,nchar))
  })
})
shinyApp(ui, server)

和一个屏幕截图:

这篇关于R拖放上的闪亮输入反应错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆