Hello! How can I pick image from computer? Like <input type="file" ... /> Is there a solution? Thanks!
I have this, but Click function do nothing Code (JavaScript): var FileUploadingPlugin = { Init: function() { var fileSelector = document.createElement('input'); fileSelector.setAttribute('type', 'file'); fileSelector.setAttribute('id', 'uploadingFile'); document.body.appendChild(fileSelector); }, Click: function() { var fileSelector = document.getElementById('uploadingFile'); fileSelector.click(); } }; mergeInto(LibraryManager.library, FileUploadingPlugin);
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.
So, I made visible html-dialog and I control them by this unity webgl plugin. Maybe it helps someone Code (JavaScript): var FileUploadingPlugin = { OpenUploadingDialog: function() { var fileSelector = document.getElementById('uploadingFileDialog'); fileSelector.style.visibility = "visible"; var fileInput = document.getElementById("fileInput"); fileInput.addEventListener( 'change', function() { var input = document.getElementById("fileInput"); var files = input.files; if (files.length > 0) { var file = files[0]; var tmppath = URL.createObjectURL(file); SendMessage("Canvas", "LoadPhotoCallback", tmppath); } else { SendMessage("Canvas", "LoadPhotoCallback", ""); } }, false ); }, CloseUploadingDialog: function() { var fileSelector = document.getElementById('uploadingFileDialog'); fileSelector.style.visibility = "hidden"; } }; mergeInto(LibraryManager.library, FileUploadingPlugin);
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): var FileUploadingPlugin = { Init: function() { inputFile = document.createElement('input'); inputFile.setAttribute('type', 'file'); inputFile.setAttribute('id', 'FileUploadingPluginInput'); inputFile.style.visibility = 'hidden'; inputFile.onclick = function (event) { this.value=null; }; inputFile.onchange = function (event) { //process file } document.body.appendChild(inputFile); }, openFileDialog: function() { document.getElementById('FileUploadingPluginInput').click(); document.getElementById('canvas').removeEventListener('click', FileUploadingPlugin.openFileDialog); }, onPointerDown: function() { if (!document.getElementById('FileUploadingPluginInput')) FileUploadingPlugin.Init(); document.getElementById('canvas').addEventListener('click', FileUploadingPlugin.openFileDialog, false); } }; mergeInto(LibraryManager.library, FileUploadingPlugin); and the C# as: Code (CSharp): using UnityEngine; using System.Collections; using System.Runtime.InteropServices; public class FileDialogButton : MonoBehaviour { [DllImport("__Internal")] private static extern void onPointerDown(); public void PointerDown () { onPointerDown (); } }
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): var FileUploadingPlugin = { onPointerDown: function() { console.log("log 1"); if (!document.getElementById('FileUploadingPluginInput')) Init(); document.getElementById('canvas').addEventListener('click', openFileDialog, false); function Init() { var inputFile = document.createElement('input'); inputFile.setAttribute('type', 'file'); inputFile.setAttribute('id', 'FileUploadingPluginInput'); //filter certain files of type with following line: //inputFile.setAttribute('accept', 'image/*'); //or accept="audio/mp3" inputFile.style.visibility = 'hidden'; inputFile.onclick = function (event) { console.log("log 3"); this.value=null; }; inputFile.onchange = function (evt) { //process file console.log("log 4"); evt.stopPropagation(); var fileInput = evt.target.files; if (!fileInput || !fileInput.length) { return; // "no image selected" } var picURL = window.URL.createObjectURL(fileInput[0]); //do something with pic url } document.body.appendChild(inputFile); } function openFileDialog() { console.log("log 2"); document.getElementById('FileUploadingPluginInput').click(); document.getElementById('canvas').removeEventListener('click', openFileDialog); } } }; mergeInto(LibraryManager.library, FileUploadingPlugin);
Replying to myself it turns out the issue is that "getElementById('canvas')" now needs to be getElementById('#canvas')
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.