Search Unity

webGL Image uploading

Discussion in 'Web' started by YuriBazila, Dec 11, 2015.

  1. YuriBazila

    YuriBazila

    Joined:
    Feb 1, 2013
    Posts:
    47
    Hello!
    How can I pick image from computer? Like <input type="file" ... />
    Is there a solution?

    Thanks!
     
  2. YuriBazila

    YuriBazila

    Joined:
    Feb 1, 2013
    Posts:
    47
    I have this, but Click function do nothing
    Code (JavaScript):
    1. var FileUploadingPlugin = {
    2.     Init: function()
    3.     {
    4.         var fileSelector = document.createElement('input');
    5.         fileSelector.setAttribute('type', 'file');
    6.         fileSelector.setAttribute('id', 'uploadingFile');
    7.         document.body.appendChild(fileSelector);
    8.     },
    9.  
    10.     Click: function()
    11.     {
    12.         var fileSelector = document.getElementById('uploadingFile');
    13.         fileSelector.click();
    14.     }
    15. };
    16.  
    17. mergeInto(LibraryManager.library, FileUploadingPlugin);
     
  3. YuriBazila

    YuriBazila

    Joined:
    Feb 1, 2013
    Posts:
    47
    Nobody knows?
     
  4. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    Hello YuriBazila.
    It is not possible to launch the <input type="file"> onclick event handler programmatically, unless you make the click() call from another event handler initiated by the user.
    For example
    <button onclick="document.getElementById('uploadingFile').click()">Initiated by user</button>
    will open the file dialog, unlike the script call.
    I believe this limitation has been introduced for security reasons.
     
    Last edited: Dec 14, 2015
  5. YuriBazila

    YuriBazila

    Joined:
    Feb 1, 2013
    Posts:
    47
    So, I made visible html-dialog and I control them by this unity webgl plugin. Maybe it helps someone

    Code (JavaScript):
    1.  
    2. var FileUploadingPlugin = {
    3.  
    4.     OpenUploadingDialog: function()
    5.     {
    6.         var fileSelector = document.getElementById('uploadingFileDialog');
    7.         fileSelector.style.visibility = "visible";
    8.  
    9.         var fileInput = document.getElementById("fileInput");
    10.  
    11.         fileInput.addEventListener(
    12.              'change',
    13.              function() {
    14.                 var input = document.getElementById("fileInput");
    15.                 var files = input.files;
    16.                
    17.                 if (files.length > 0)
    18.                 {
    19.                     var file = files[0];
    20.                     var tmppath = URL.createObjectURL(file);
    21.                     SendMessage("Canvas", "LoadPhotoCallback", tmppath);
    22.                 }
    23.                 else
    24.                 {
    25.                     SendMessage("Canvas", "LoadPhotoCallback", "");
    26.                 }
    27.              },
    28.              false
    29.           );
    30.     },
    31.     CloseUploadingDialog: function()
    32.     {
    33.         var fileSelector = document.getElementById('uploadingFileDialog');
    34.         fileSelector.style.visibility = "hidden";
    35.     }
    36. };
    37.  
    38. mergeInto(LibraryManager.library, FileUploadingPlugin);
     
  6. alexsuvorov

    alexsuvorov

    Unity Technologies

    Joined:
    Nov 15, 2015
    Posts:
    327
    As mentioned before, you are not able to do this using the OnClick event, however if you want the file dialog to popup when you click a GUIElement like UI Button, there is a possible workaround.

    The idea is to register a canvas onclick event handler at the moment when the user clicks a button. This way the canvas onclick event will be triggered directly by the user, so the <input type="file"> click() can be successfully executed. The canvas onclick event handler is executed before the UI Button OnClick, so you should register the handler in advance. For example, in the Pointer Down event handler (available through the Event Trigger component). The plugin code would then look like:

    Code (JavaScript):
    1. var FileUploadingPlugin = {
    2.     Init: function() {
    3.         inputFile = document.createElement('input');
    4.         inputFile.setAttribute('type', 'file');
    5.         inputFile.setAttribute('id', 'FileUploadingPluginInput');
    6.         inputFile.style.visibility = 'hidden';
    7.         inputFile.onclick = function (event) {
    8.             this.value=null;
    9.         };
    10.         inputFile.onchange = function (event) {
    11.             //process file
    12.         }
    13.         document.body.appendChild(inputFile);
    14.     },
    15.     openFileDialog: function() {
    16.             document.getElementById('FileUploadingPluginInput').click();
    17.             document.getElementById('canvas').removeEventListener('click', FileUploadingPlugin.openFileDialog);
    18.     },
    19.     onPointerDown: function() {
    20.       if (!document.getElementById('FileUploadingPluginInput'))
    21.             FileUploadingPlugin.Init();
    22.       document.getElementById('canvas').addEventListener('click', FileUploadingPlugin.openFileDialog, false);
    23.     }
    24. };
    25.  
    26. mergeInto(LibraryManager.library, FileUploadingPlugin);
    and the C# as:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Runtime.InteropServices;
    4.  
    5. public class FileDialogButton : MonoBehaviour {
    6.     [DllImport("__Internal")]
    7.     private static extern void onPointerDown();
    8.  
    9.     public void PointerDown () {
    10.         onPointerDown ();
    11.     }
    12. }
     
    Last edited: Dec 15, 2015
    Muteking and LE0NIDAS like this.
  7. pera2

    pera2

    Joined:
    Aug 10, 2016
    Posts:
    14
    I had to modify js code a little bit to make it work with latest unity. All function had to be placed within onPointerDown function:

    Code (JavaScript):
    1. var FileUploadingPlugin = {
    2.  
    3.     onPointerDown: function() {
    4.       console.log("log 1");
    5.       if (!document.getElementById('FileUploadingPluginInput'))
    6.             Init();
    7.       document.getElementById('canvas').addEventListener('click', openFileDialog, false);
    8.  
    9.       function Init() {
    10.           var inputFile = document.createElement('input');
    11.           inputFile.setAttribute('type', 'file');
    12.           inputFile.setAttribute('id', 'FileUploadingPluginInput');
    13.        
    14.           //filter certain files of type with following line:
    15.           //inputFile.setAttribute('accept', 'image/*'); //or accept="audio/mp3"
    16.        
    17.           inputFile.style.visibility = 'hidden';
    18.        
    19.           inputFile.onclick = function (event) {
    20.               console.log("log 3");
    21.               this.value=null;
    22.           };
    23.  
    24.           inputFile.onchange = function (evt) {
    25.               //process file
    26.               console.log("log 4");
    27.               evt.stopPropagation();
    28.               var fileInput = evt.target.files;
    29.               if (!fileInput || !fileInput.length) {
    30.                   return; // "no image selected"
    31.               }
    32.  
    33.               var picURL = window.URL.createObjectURL(fileInput[0]);
    34.            
    35.               //do something with pic url
    36.           }
    37.           document.body.appendChild(inputFile);
    38.       }
    39.  
    40.       function openFileDialog() {
    41.               console.log("log 2");
    42.               document.getElementById('FileUploadingPluginInput').click();
    43.               document.getElementById('canvas').removeEventListener('click', openFileDialog);
    44.       }
    45.  
    46.     }
    47. };
    48.  
    49. mergeInto(LibraryManager.library, FileUploadingPlugin);
     
  8. ibyte

    ibyte

    Joined:
    Aug 14, 2009
    Posts:
    1,047
    Replying to myself it turns out the issue is that "getElementById('canvas')" now needs to be getElementById('#canvas')
     
    Last edited: Sep 23, 2019
  9. doctorpangloss

    doctorpangloss

    Joined:
    Feb 20, 2013
    Posts:
    270
    This problem has been around forever and I don't really know why Unity hasn't fixed it!
     
  10. jukka_j

    jukka_j

    Unity Technologies

    Joined:
    May 4, 2018
    Posts:
    953
    The originally posted issue looks like it was a problem in the code posted in this forum thread, so the appropriate fix is an update to the code in this forum thread (like was done in ibyte's reply above).

    Btw, definitely recommend using document.querySelector() function instead of document.getElementById(), as the former allows more flexible mechanism of targeting DOM elements (https://www.w3schools.com/cssref/css_selectors.asp) and can be more useful in scenarios where page has multiple canvases.
     
    ibyte likes this.