title: Drag and drop data into shiny app
body: <p>How can I drag and drop data into a shiny app?  I can drag and drop into an area and read it with javascript, but I'm not sure how to have shiny register it so I can process it on the server.  Here is an example setup -- it's kinda long b/c I don't think there is a javascript function builtin to deal with drag-n-drop.</p>
  
  <p>It currently should look like the following when run and a dataset "dat.csv" is dragged in.  The goal is register the data that has been drag-n-dropped into a variable in <code>input</code> so it can be processed in R.
  <a href="https://i.stack.imgur.com/9eLxS.png"><img src="https://i.stack.imgur.com/9eLxS.png" alt="enter image description here"></a></p>
  
  <h3>ui.R</h3>
  
  <pre><code>library(shiny)
  
  ui &lt;- shinyUI(
    fluidPage(
      tags$head(tags$link(rel="stylesheet", href="css/styles.css", type="text/css"),
        tags$script(src="getdata.js")),
      h3(id="data-title", "Drop Datasets"),
      div(class="col-xs-12", id="drop-area", ondragover="dragOver(event)", 
        ondrop="dropData(event)"),
      tableOutput('table'),  # doesn't do anything now
  
      ## debug
      div(class="col-xs-12",
        tags$hr(style="border:1px solid grey;width:150%"),
        tags$button(id="showData", "Show", class="btn btn-info", 
          onclick="printData('dat.csv')")),
      div(id="data-output")  # print the data
    )
  )
  </code></pre>
  
  <h3>server.R</h3>
  
  <pre><code>## Make a sample dataset
  # write.csv(data.frame(a=1:10, b=letters[1:10]), "dat.csv", row.names=FALSE)
  server &lt;- function(input, output, session) {
    output$table &lt;- renderTable(input$data)  # this variable doesn't exist
  }
  </code></pre>
  
  <h3>www/getdata.js</h3>
  
  <pre><code>var datasets = {};
  var dragOver = function(e) { e.preventDefault(); };
  var dropData = function(e) {
      e.preventDefault();
      handleDrop(e.dataTransfer.files);
  };
  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;
          var div = document.createElement("div");
          var src = "https://cdn0.iconfinder.com/data/icons/office/512/e42-512.png";
          div.id = "datasets";
          div.innerHTML = [
              "&lt;img class='thumb' src='", src, "' title='", encodeURI(file.name),
              "'/&gt;", "&lt;br&gt;", file.name, "&lt;br&gt;"].join('');
          document.getElementById("drop-area").appendChild(div);
          };
      })(f);
      reader.readAsText(f);
      }
  };
  // debug
  var printData = function(data) {
      var div = document.createElement("div");
      div.innerHTML = datasets[data];
      document.getElementById("data-output").appendChild(div);
  };
  </code></pre>
  
  <h3>www/css/styles.css</h3>
  
  <pre><code>#data-title {
      text-align:center;
  }
  
  #drop-area {
      background-color:#BCED91;
      border:2px solid #46523C;
      border-radius:25px;
      height:90px;
      overflow:auto;
      padding:12px;
  }
  
  #drop-area #datasets {
      display:inline-block;
      font-size:small;
      margin-right:8px;
      text-align:center;
      vertical-align:top;
  }
  
  .thumb {
      height:45px;
  }
  </code></pre>