Search code examples
javascripthtmlcssinputcytoscape

html input with cytoscape.js fails to open the dialog window


I am building an interactive graph app where the user would upload a data file. The app would then build the graph from the input file.

I am having problems with making the input work with the cytoscape . More specifically, the file dialog window does not pop up when I include the div. That is, the input button is not responsive unless I comment out the cytoscape .

Please see the code below. I guess, this is not cytoscape specific. However, I could not get to the bottom of this, so I am posting the complete instance of the problem.

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <script src="cytoscape.js"></script>
</head>

<style>
    #cy {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0px;
        left: 0px;
    }
</style>

<body>
    
  <form name="uploadForm">
    <div>
      <input id="uploadInput" type="file" name="myFiles" multiple>
      selected files: <span id="fileNum">0</span>;
      total size: <span id="fileSize">0</span>
    </div>
    <div><input type="submit" value="Send file"></div>
  </form>
 
  <div>
      <h1>This!</h1>
  </div>    
  <div id="cy"></div> 
  
<script>
  function updateSize() {
    let nBytes = 0,
        oFiles = this.files,
        nFiles = oFiles.length;
    for (let nFileId = 0; nFileId < nFiles; nFileId++) {
      nBytes += oFiles[nFileId].size;
    }
    let sOutput = nBytes + " bytes";
    // optional code for multiples approximation
    const aMultiples = ["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
    for (nMultiple = 0, nApprox = nBytes / 1024; nApprox > 1; nApprox /= 1024, nMultiple++) {
      sOutput = nApprox.toFixed(3) + " " + aMultiples[nMultiple] + " (" + nBytes + " bytes)";
    }
    // end of optional code
    document.getElementById("fileNum").innerHTML = nFiles;
    document.getElementById("fileSize").innerHTML = sOutput;
    console.log("AAAA!")
  }

  document.getElementById("uploadInput").addEventListener("change", updateSize, false);
</script>

<script>
    // https://blog.js.cytoscape.org/2016/05/24/getting-started/
  var cy = cytoscape({
    container: document.getElementById('cy'),
    // ~~~~~~~~~~~~~~~~~~~
    elements: [
    { data: { id: 'a' } },
    { data: { id: 'b' } },
    {
        data: {
        id: 'ab',
        source: 'a',
        target: 'b'
        }
    }],
    // ~~~~~~~~~~~~~~~~~~~
    style: [
        {
            selector: 'node',
            style: {
                shape: 'hexagon',
                'background-color': 'red',
                label: 'data(id)'
            }
        }]      
});
cy.layout({
    name: 'circle'
}).run();
</script>

</body>
</html>

Solution

  • It's related with the z-index of the divs. In your case, because you don't assign z-indexes to the divs and add cy div at the end, it is rendered on top, so you cannot interact with the buttons.

    You can assign a z-index to cy div such as -1 to send it to the background:

    #cy {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0px;
        left: 0px;
        z-index: -1;
    }
    

    But in this case you won't be able to interact with the top part of the cy canvas. A better solution is to change the top attribute to some value such as 250px so that cy canvas is started to be rendered below the buttons and texts:

    #cy {
        width: 100%;
        height: 100%;
        position: absolute;
        top: 250px;
        left: 0px;
    }