Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set file-input file from url

I have a file input:

<input type="file" id="myImageInput" accept="image/*">

I have a preview img:

<img src="http://myImageUrl" id="myImagePreview">

I want to set the image as a file for the file-input#myImageInput.

What I try:

  1. Create Base64 from the img#myImagePreview:
function toDataUrl(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        var reader = new FileReader();
        reader.onloadend = function() {
            callback(reader.result);
        }
        reader.readAsDataURL(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

let base64Image;
toDataUrl("http://myImageUrl",function(x){
    base64Image = x;
})
  1. Create DataTransfer and add the base64Image to it:
const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File(['myNewFile'], base64Image ));
document.querySelector('#myImageInput').files = dT.files;
  1. Console.log the #myImageInput.files:
0: File
lastModified: 1593986842957
lastModifiedDate: Mon Jul 06 2020 00:07:22 GMT+0200 (Central European Summer Time) {}
name: "data:image/jpeg;base64,/9j/4AAQSkZJRgABCSAQAASABIAAADD"
size: 9
type: ""
webkitRelativePath: ""

This doesn't look right but it actually set a "file"...

  1. Now I try to preview the new image from the myImageInput:
function previewFile() {
  var preview = document.querySelector('#myImagePreview');
  var file    = document.querySelector('#myImageInput').files[0];
  var reader  = new FileReader();

  reader.onloadend = function () {
    preview.src = reader.result;
    console.log(reader.result);
  }

  if (file) {
    reader.readAsDataURL(file);
  } else {
    preview.src = "";
  }
}

previewFile();

But the image is broken. #myImagePreview:

<img src="data:application/octet-stream;base64,bXlOZyXdGacWxl" id="myImagePreview">

Do I need to feed the DataTransfer.items a blob? a base64 or a fileObject to make this work?

like image 360
Suisse Avatar asked Jul 05 '20 22:07

Suisse


People also ask

How do I assign a file to an input type file?

The only way to set the value of a file input is by the user to select a file. This is done for security reasons. Otherwise you would be able to create a JavaScript that automatically uploads a specific file from the client's computer.

How do you create an input from a file in HTML?

The <input type="file"> defines a file-select field and a "Browse" button for file uploads. To define a file-select field that allows multiple files to be selected, add the multiple attribute. Tip: Always add the <label> tag for best accessibility practices!

How do I change the Choose file button in CSS?

You can simply use ::-webkit-file-upload-button in css and style your Choose file button.


Video Answer


1 Answers

Your File constructor is incorrect, the file data is the first parameter and the filename the second.
Also you are putting base64 data into the file instead binary data.
Below the bob is used to create the File instead of a base64 string.

function toDataUrl(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
        callback(xhr.response);
    };
    xhr.open('GET', url);
    xhr.responseType = 'blob';
    xhr.send();
}

let image;
toDataUrl("http://myImageUrl",function(x){
    image = x;
})

...

const dT = new ClipboardEvent('').clipboardData || // Firefox < 62 workaround exploiting https://bugzilla.mozilla.org/show_bug.cgi?id=1422655
new DataTransfer(); // specs compliant (as of March 2018 only Chrome)
dT.items.add(new File([image], 'myNewFile'));
document.querySelector('#myImageInput').files = dT.files;
like image 149
Musa Avatar answered Sep 20 '22 12:09

Musa