Load multiple picture files with angularjs - javascript

I found this useful link which shows how to load picture from your local pc with a directive (newbie w/angular). But I don't know where to modify it to display also the selected images. How could I achieve this? I found that many examples like this that only lists the filenames.
I found this approach which loads the file and I adapted it to load multiple files. By this doesn't use angular.
window.onload = function() {
var fileInput = document.getElementById('fileInput');
var fileDisplayArea = document.getElementById('fileDisplayArea');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var imageType = /image.*/;
if (file.type.match(imageType)) {
var reader = new FileReader();
reader.onload = function(e) {
fileDisplayArea.innerHTML = "";
var img = new Image();
img.src = reader.result;
fileDisplayArea.appendChild(img);
}
reader.readAsDataURL(file);
} else {
fileDisplayArea.innerHTML = "File not supported!"
}
});
What would be a better approach. I want to load multiple files, display and finally upload them as byteArray.

The below code will allow selection of multiple files and display them on the webpage. For uploading them you can use Formdata Here is the link to use FormData . Also you can find several post explaining how to upload files using FormData you just have to ask Google.
window.onload = function(){
//Check File API support
if(window.File && window.FileList && window.FileReader)
{
var filesInput = document.getElementById("fileInput");
filesInput.addEventListener("change", function(event){
var files = event.target.files; //FileList object
var output = document.getElementById("fileDisplayArea");
output.innerHTML="";
for(var i = 0; i< files.length; i++)
{
var file = files[i];
//Only pics
if(!file.type.match('image'))
continue;
var picReader = new FileReader();
picReader.addEventListener("load",function(event){
var picFile = event.target;
var div = document.createElement("div");
div.innerHTML = "<img class='thumbnail' src='" + picFile.result + "'" +
"title='" + picFile.name + "'/>";
output.insertBefore(div,null);
});
//Read the image
picReader.readAsDataURL(file);
}
});
}
else
{
console.log("Your browser does not support File API");
}
}
html {
font-family: Helvetica, Arial, sans-serif;
font-size: 100%;
background: #333;
}
#page-wrapper {
width: 600px;
background: #FFF;
padding: 1em;
margin: 1em auto;
min-height: 300px;
border-top: 5px solid #69c773;
box-shadow: 0 2px 10px rgba(0,0,0,0.8);
}
h1 {
margin-top: 0;
}
img {
max-width: 100%;
}
#fileDisplayArea {
margin-top: 2em;
width: 100%;
overflow-x: auto;
}
<div id="page-wrapper">
<h1>Image File Reader</h1>
<div>
Select an image file:
<input type="file" id="fileInput" multiple>
</div>
<div id="fileDisplayArea"></div>
</div>

Related

What do we do if we want to insert multiple images uploaded by dragdrop in one line at a time?

i used by javascrip upload multiple file but that files insert different columns.
Why is it that when uploading multiple files with drag drop, they are written in multiple rows instead of one line in the database?
Pictured is a view of the data after inserting it into the database
My php Code is : uploads.php
if(isset($_FILES)){
$upload_dir = "upload/";
$fileName = strtolower(pathinfo($_FILES["files"]["name"], PATHINFO_EXTENSION));
$new_file_name = rand() . '.' . $fileName;
$uploaded_file = $upload_dir.$new_file_name;
if(move_uploaded_file($_FILES['files']['tmp_name'],$uploaded_file)){
}
$content = $_POST['textpost'];
$data = array(
':file' => $new_file_name,
':uploaded_on' => date("Y-m-d H:i:s"),
':content' => $content,
);
$query = "
INSERT INTO images
(name, uploaded_on ,content)
VALUES (:name,:uploaded_on,:content)
";
$statement = $connect->prepare($query);
$statement->execute($data);
}
The Below is the code I originally used. I used these codes as examples from other people’s codes. Then I made some changes myself and added a little functionality. For example, I added a few codes, such as deleting images, separating images and videos, and brought them to the function I needed. But the problem with me now is that When uploading multiple images at the same time as text, All data sent are insert into separate rows, Finally when I select the data from the database the content and images are not select out correctly.My goal is to insert images and text into a single line.
My javascript Code is :index.html
var dropRegion = document.getElementById("drop-region"),
// where images are previewed
imagePreviewRegion = document.getElementById("image-preview");
var file_drag_area = document.getElementById("file_drag_area");
var images_button = document.getElementById("images_btn");
var submit = document.getElementById("submit");
// open file selector when clicked on the drop region
var fakeInput = document.createElement("input");
fakeInput.type = "file";
fakeInput.accept = "video/*,image/*";
fakeInput.multiple = true;
images_button.addEventListener('click', function() {
fakeInput.click();
});
fakeInput.addEventListener("change", function() {
var files = fakeInput.files;
handleFiles(files);
});
function preventDefault(e) {
e.preventDefault();
e.stopPropagation();
}
file_drag_area.addEventListener('dragenter', preventDefault, false)
file_drag_area.addEventListener('dragleave', preventDefault, false)
file_drag_area.addEventListener('dragover', preventDefault, false)
file_drag_area.addEventListener('drop', preventDefault, false)
dropRegion.addEventListener('dragenter', preventDefault, false)
dropRegion.addEventListener('dragleave', preventDefault, false)
dropRegion.addEventListener('dragover', preventDefault, false)
dropRegion.addEventListener('drop', preventDefault, false)
function handleDrop(e) {
var dt = e.dataTransfer,
files = dt.files;
handleFiles(files)
}
dropRegion.addEventListener('drop', handleDrop, false);
file_drag_area.addEventListener('drop', handleDrop, false);
// when drag file the border change to other dotted
file_drag_area.addEventListener("dragenter", function(event) {
if ( event.target.className == "file_drag_area" ) {
event.target.style.border = "3px dotted #79d4ff";
}
});
// when drag file the border display none
file_drag_area.addEventListener("dragleave", function(event) {
if ( event.target.className == "trigger_popup_fricc_wrapper" ) {
event.target.style.border = "";
}
});
file_drag_area.addEventListener("drop", function(event) {
if ( event.target.className == "trigger_popup_fricc_wrapper" ) {
event.target.style.border = "";
}
});
function handleFiles(files) {
for (var i = 0, len = files.length; i < len; i++) {
if (validateImage(files[i]))
previewAnduploadImage(files[i]);
}
}
function validateImage(image) {
// check the type
var validTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg','video/mp4', 'video/mkv', 'video/webm'];
var vedioType = validTypes.includes('video/mp4', 'video/mkv', 'video/webm');
if (validTypes.indexOf( image.type ) === -1 && vedioType.indexOf( video.type ) === -1) {
alert("Invalid File Type");
return false;
}
// check the size
var maxSizeInBytes = 10e6; // 10MB
if (image.size > maxSizeInBytes) {
alert("File too large");
return false;
}
return true;
}
function previewAnduploadImage(image) {
var fileType = image.type;
var match = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg','video/mp4', 'video/mkv', 'video/webm'];
if ((fileType == match[0]) || (fileType == match[1]) || (fileType == match[2]) || (fileType == match[3])) {
var imgView = document.createElement("div");
imgView.className = "image-view";
imagePreviewRegion.appendChild(imgView);
var icon = document.createElement("div")
icon.className = "image-icon";
//icon.setAttribute("onclick", "remove_image()");
imgView.appendChild(icon);
var remove = document.createElement("img")
remove.className = "img_class";
remove.setAttribute("height", "20px");
remove.setAttribute("width", "20px");
remove.setAttribute("src", "../../assets/images/cancel.png");
icon.appendChild(remove);
// previewing image
var img = document.createElement("img");
img.className = "remove_input";
img.setAttribute("height", "200px");
img.setAttribute("width", "300px");
imgView.appendChild(img);
var reader = new FileReader();
reader.onload = function(e) {
img.src = e.target.result;
}
reader.readAsDataURL(image);
}else if ((fileType == match[4]) || (fileType == match[5]) || (fileType == match[6])) {
// show video
var video = document.createElement("video")
video.classList.add("obj");
video.file = image;
video.className = "preview_vedio";
video.controls = true;
video.autoplay = true;
video.setAttribute("width", "500");
video.setAttribute("height", "300");
//icon.setAttribute("onclick", "remove_image()");
imagePreviewRegion.appendChild(video);
var reader = new FileReader();
reader.onload = function(e) {
video.src = e.target.result;
}
reader.readAsDataURL(image);
}
var formData = new FormData();
formData.append('image', image);
formData.append('action', 'files');
//formData.append('vedio', vediofiles);
$("#drop-region").css("display", "block");
$("#drop-region").slideDown("slow")
addEventListener('submit', (event) => {
var uploadLocation = 'uploads.php';
var ajax = new XMLHttpRequest();
ajax.open("POST", uploadLocation, true);
ajax.onreadystatechange = function(e) {
if (ajax.readyState === 4) {
if (ajax.status === 200) {
//var myObj = JSON.parse(this.responseText);
} else {
// error!
}
}
}
ajax.upload.onprogress = function(e) {
// change progress
// (reduce the width of overlay)
var perc = (e.loaded / e.total * 100) || 100,
width = 100 - perc;
overlay.style.width = width;
}
ajax.send(formData);
});
}
textarea
{
width: 100%;
margin: 0px;
padding: .2em;
border: none;
outline-width: 0;
text-align: start;
unicode-bidi: plaintext;
font-weight: 400;
cursor: text;
background-color: #ffffff;
overflow:hidden;
resize: none;
font-size: 18px;
}
input#submit {
width: 100%;
color: white;
background: #79d4ff;
font-size: 18px;
border: none;
border-radius: 8px;
outline-width: 0;
line-height: 2;
}
input#submit:hover
{
background: #3da0f5;
}
input#submit:focus{width: 98%;}
#drop-region {
background-color: #fff;
border-radius:20px;
box-shadow:0 0 35px rgba(0,0,0,0.05);
padding:60px 40px;
text-align: center;
cursor:pointer;
transition:.3s;
display:none;
}
#drop-region:hover {
box-shadow:0 0 45px rgba(0,0,0,0.1);
}
#image-preview {
margin-top:20px;
}
#image-preview .image-view {
display: inline-block;
position:relative;
margin-right: 13px;
margin-bottom: 13px;
}
#image-preview .image-view img {
max-width: 300px;
max-height: 300px;
transform: scale(.9);
transition: .4s;
}
#image-preview .overlay {
position: absolute;
width: 100%;
height: 100%;
top: 0;
right: 0;
z-index: 2;
background: rgba(255,255,255,0.5);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<form id="fupForm"enctype="multipart/form-data" accept-charset="utf-8">
<textarea style="direction:ltr;" name="post_content" class="file_drag_area" id="file_drag_area" maxlength="1000" placeholder="Greate Post..." ></textarea>
<div id="drop-region">
<div id="image-preview">
</div>
</div>
<button type="button" class="emoji_button" id="images_btn"><img src="../../assets/images/image.png" width="25px" height="25px" ></button>
<input type="submit" name="submit" id="submit" class="btn btn-primary" value="Send Post" />
</form>
For your case, when you drag and drop the files (file upload), you will trigger the following function:
function handleFiles(files) {
for (var i = 0, len = files.length; i < len; i++) {
if (validateImage(files[i]))
previewAnduploadImage(files[i]);
}
}
It is obvious that this "handleFiles" function will process the files one by one. Hence the php is called ONCE for every file uploaded --- and that explains why the files are saved into separate records.
The above should explain what you encounter. So if you want to save the data into a single record, you need to amend the above codes

How to display uploaded image in CSS background URL property using input file API - vanilla Javascript

The initial project had an array with file names stored in there and the image slider would display them.
I am trying to create the upload functionality where the user can upload an image and that image would then be pushed to the array.
I've tried utilizing the URL.createObjectURL method on the uploaded file and pushing it to the display but there's an error when the slide arrives at the array index.
The file comes out as 'blob:http etc...' and so i've tried removing 'blob' from the string and still receiving an error.
HTML:
<div id="container">
<button class="button" id="leftButton"><i class="fa fa-arrow-left"></i></button>
<button class="button" id="rightButton"><i class="fa fa-arrow-right"></i></button>
</div>
<div class="upload">
<p><input type='file' name='image' id="input"></p>
</div>
CSS:
#container {
margin: 100px auto;
height: 500px;
width: 900px;
border: 7px solid #3e92cc;
border-radius: 10px;
background: url('images/one.jpg');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
Javascript:
let container = document.getElementById("container");
let rightButton = document.getElementById("rightButton");
let leftButton = document.getElementById("leftButton");
let images = ["one.jpg", "two.jpg", "three.jpg", "four.jpg", "five.jpg"];
let imagesIndex = 0;
const inputElement = document.getElementById("input");
let newURL;
//Add background to slider
function addBackground() {
if (!images[imagesIndex].includes('http')) {
container.style.background = `url('images/${images[imagesIndex]}')`;
} else {
container.style.background = `url('${images[imageIndex]}')`;
}
container.style.backgroundPosition = "center";
container.style.backgroundRepeat = "no-repeat";
container.style.backgroundSize = "cover";
}
// upload files
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
const objectURL = window.URL.createObjectURL(fileList[0]);
//remove 'blob:';
newURL = objectURL.replace('blob:', '');
console.log(newURL);
images.push(newURL);
}
// Event listeners
inputElement.addEventListener("change", handleFiles, false);
rightButton.addEventListener("click", function () {
imagesIndex++;
if (imagesIndex >= images.length) {
imagesIndex = 0;
}
console.log(imagesIndex);
addBackground();
})
leftButton.addEventListener("click", function () {
imagesIndex--;
if (imagesIndex < 0) {
imagesIndex = images.length - 1;
}
console.log(imagesIndex);
addBackground();
})
Don't remove blob: it's required in the URL scheme
// upload files
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
const objectURL = window.URL.createObjectURL(fileList[0]);
//remove 'blob:';
//newURL = objectURL.replace('blob:', '');
console.log(objectURL);
images.push(objectURL);
}
Corrected typo in imagesIndex
//Add background to slider
function addBackground() {
if (!images[imagesIndex].includes('http')) {
container.style.background = `url('images/${images[imagesIndex]}')`;
} else {
container.style.background = `url('${images[imagesIndex]}')`;
}
//.. other code
}

How transfer files (or folders) via Ajax by d'n'd?

I want to upload folder to server by d'n'd via AJAX. But already, I have troubles with upload files.
I use e.dataTransfer.items and webkitGetAsEntry() to check - is it file or folder?
If it's file, in function traverseFileTree I get file, but I can't append it to formData.
If I use e.dataTransfer.files, I don't know what is it. File or Folder because webkitGetAsEntry() get error.
What I do wrong?
How transfer files to global array $_FILES.
Source (upload.php):
echo "<pre>";
print_r ($_FILES);
echo "</pre>";
Source (index.html):
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop</title>
<style>
body {
background: rgba(211,211,100, .5);
font: 20px Arial;
}
.dropzone {
width: 300px;
height: 300px;
border: 2px dashed #aaa;
color: #aaa;
line-height: 280px;
text-align: center;
position: absolute;
left: 50%;
margin-left: -150px;
top: 50%;
margin-top: -150px;
}
.dropzone.dragover {
color: green;
border: 2px dashed #000;
}
</style>
</head>
<body>
<p>Loaded files:</p>
<div id="uploads">
<ul>
</ul>
</div>
<div class="dropzone" id="dropzone">Drop files</div>
<script>
(function() {
var formData = new FormData();
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(e) {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
e.preventDefault();
upload(e.dataTransfer.items);
};
function traverseFileTree(item, path) {
path = path || "";
if (item.isFile) {
item.file(function(file) {
console.log(file); // show info
formData.append('file[]', file); // file exist, but don't append
});
} /*else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(function(entries) {
for (var i=0; i<entries.length; i++) {
traverseFileTree(entries[i], path + item.name + "/");
}
});
}*/
}
var upload = function(items) {
var xhr = new XMLHttpRequest();
for(var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree(item,'');
}
}
xhr.onload = function() {
console.log(this.responseText);
};
xhr.open('post', 'upload.php');
xhr.send(formData);
};
dropzone.ondragover = function() {
this.className = 'dropzone dragover';
this.innerHTML = 'Mouse up';
return false;
};
dropzone.ondragleave = function() {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
return false;
};
})();
</script>
Both file() and readEntries() return results asynchronously. Since it is impossible to know for certain how many files or directories, which themselves could contain additional directories containing still more files or folders, will be selected and dropped by user, the a single or recursive calls to traverseFileTree require some mechanism to determine when all asynchronous operations have completed. This can be achieved using one or more of several approaches.
The present approach increments a variable n, pushes each individual file to an array uploads. If n is 0, process the first file; increment n so that its value 1 greater than the array containing files .length until the array .length is equal to n - 1
uploads.length === n - 1 || n === 0
then copy uploads array using .slice(), set uploads.length and n to 0, pass array of files to function processFiles where files are appended to FormData() object, call to XMLHttpRequest() is made.
<!DOCTYPE html>
<html>
<head>
<title>Drag and Drop</title>
<style>
body {
background: rgba(211, 211, 100, .5);
font: 20px Arial;
}
.dropzone {
width: 300px;
height: 300px;
border: 2px dashed #aaa;
color: #aaa;
line-height: 280px;
text-align: center;
position: absolute;
left: 50%;
margin-left: -150px;
top: 50%;
margin-top: -150px;
}
.dropzone.dragover {
color: green;
border: 2px dashed #000;
}
</style>
</head>
<body>
<p>Loaded files:</p>
<div id="uploads">
<ul>
</ul>
</div>
<div class="dropzone" id="dropzone">Drop files</div>
<script>
(function() {
var n = 0, uploads = [];
var dropzone = document.getElementById("dropzone");
dropzone.ondrop = function(e) {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
e.preventDefault();
upload(e.dataTransfer.items);
};
function processFiles(files) {
console.log("files:", files);
alert("processing " + files.length + " files");
var formData = new FormData();
// append files to `formData`
for (file of files) {
formData.append("file[]", file, file.name)
}
// check `formData` entries
var curr = 0;
for (data of formData.entries()) {
console.log("formData entry " + curr, data);
++curr;
}
delete curr;
// do ajax stuff here
var xhr = new XMLHttpRequest();
xhr.onload = function() {
console.log(this.responseText);
};
xhr.open("POST", "upload.php");
xhr.send(formData);
}
function traverseFileTree(item, path) {
var handleFiles = function handleFiles(item, path) {
path = path || "";
if (item.isFile) {
item.file(function(file) {
uploads.push(file);
console.log(file, n, uploads.length); // show info
if (uploads.length === n - 1 || n === 0) {
alert("traverseFiles complete, uploads length: "
+ uploads.length);
var files = uploads.slice(0);
n = uploads.length = 0;
processFiles(files)
}
});
} else if (item.isDirectory) {
var dirReader = item.createReader();
dirReader.readEntries(function(entries) {
// increment `n` here
n += entries.length;
for (var i = 0; i < entries.length; i++) {
handleFiles(entries[i], path + item.name + "/");
}
});
}
}
handleFiles(item, path);
}
var upload = function(items) {
if (n !== 0 && uploads.length !== 0) {
n = uploads.length = 0;
}
for (var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
traverseFileTree(item, "");
}
}
};
dropzone.ondragover = function() {
this.className = 'dropzone dragover';
this.innerHTML = 'Mouse up';
return false;
};
dropzone.ondragleave = function() {
this.className = 'dropzone';
this.innerHTML = 'Drop files';
return false;
};
})();
</script>
</body>
</html>
plnkr http://plnkr.co/edit/OdFrwYH2gmbtvHfq3ZjH?p=preview
See also How can I filter out directories from upload handler in Firefox? , How to read files from folder

Google Apps Script Works as Web App but Not Spreadsheet Script

I've got a stand-alone script deployed as a Web App. My code is working exactly as it should as a Web App. However, my goal is to use that code in a Spreadsheet Project.
I copied and pasted the code into a Spreadsheet Script and made a few alterations to make it work in a pop-up Modal dialog window, but it does not work as it does as a deployed web app. The code seems to not return any data to Code.gs. After running alerts at various points along the code path I have discovered the point of failure but am not sure how to address it.
Code from the working WebApp (2 files: Code.gs & form.html):
## Code.gs file ##
function doGet() {
return HtmlService.createHtmlOutputFromFile('form')
.setSandboxMode(HtmlService.SandboxMode.IFRAME);
}
function uploadFileToDrive(base64Data, fileName, totalFiles, finalCount) {
try{
var splitBase = base64Data.split(','),
type = splitBase[0].split(';')[0].replace('data:','');
var byteCharacters = Utilities.base64Decode(splitBase[1]);
var ss = Utilities.newBlob(byteCharacters, type);
ss.setName(fileName);
var dropbox = "stuff"; // Folder Name
var folder, folders = DriveApp.getFoldersByName(dropbox); // Get folders by name
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var file = folder.createFile(ss);
// BEGIN LOGGING FILE NAMES AND IDs
var dropboxId = "SOME_FOLDER_ID_HERE" // Folder ID
var theFolder = DriveApp.getFolderById(dropboxId); // Get folder by ID
var list = [];
var theBlobs = [];
if (totalFiles == finalCount) {
var files = theFolder.getFiles();
while (files.hasNext()) {
var theFile = files.next();
list.push(theFile.getId());
}
for (var i = 0; i < list.length; i++) {
Logger.log(DriveApp.getFileById(list[i]).getName() + " : " + list[i]);
theBlobs.push(DriveApp.getFileById(list[i]).getBlob());
}
Logger.log(theBlobs);
// END LOGGING FILE NAMES AND IDs
// BEGIN ZIPPING UP FILES
var newZip = theFolder.createFile(Utilities.zip(theBlobs, 'zippedFiles.zip'));
var zipId = newZip.getId();
Logger.log("Zip Id: " + zipId);
// END ZIPPING UP FILES
// BEGIN TRASHING UPLOADED FILES
for (var i = 0; i < list.length; i++) {
DriveApp.getFileById(list[i]).setTrashed(true);
}
// END TRASHING UPLOADED FILES
}
return file.getName();
}catch(e){
return 'Error: ' + e.toString();
}
}
## form.html ##
<body>
<div id="formcontainer">
<form id="myForm">
<label for="myFile">Upload File(s):</label><br />
<input type="file" name="filename" id="myFile" multiple />
<input type="button" class="blue" value="Submit" onclick="iteratorFileUpload()" /><br /><br />
</form>
</div>
<div id="output"></div>
<div id="progressbar">
<div class="progress-label"></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://googledrive.com/host/0By0COpjNTZPnZTBvVGZOSFRhREE/add-ons.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>
var numUploads = {};
numUploads.done = 0 ;
numUploads.total = 0 ;
// Upload the files into a folder in drive...set to send them all to one folder (specificed in the .gs file)
function iteratorFileUpload() {
var allFiles = document.getElementById('myFile').files;
if (allFiles.length == 0) {
alert('No file selected!');
} else { // Show Progress Bar
var myCount = 0; // Begin count to compare loops through
numUploads.total = allFiles.length;
$('#progressbar').progressbar({
value : false
});
$(".progress-label").html('Preparing files..');
// Send a file at a time
for (var i = 0; i < allFiles.length; i++) {
myCount++; // Increment count each time before sending the file to drive
sendFileToDrive(allFiles[i], allFiles.length, myCount);
}
}
}
function sendFileToDrive(file, totalFiles, newCount) {
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
google.script.run.withSuccessHandler(updateProgressbar).uploadFileToDrive(content, file.name, totalFiles, newCount);
}
reader.readAsDataURL(file);
}
function updateProgressbar( idUpdate ){
numUploads.done++;
var porc = Math.ceil((numUploads.done / numUploads.total)*100);
$("#progressbar").progressbar({value: porc });
$(".progress-label").text(numUploads.done +'/'+ numUploads.total);
if( numUploads.done == numUploads.total ){
numUploads.done = 0;
};
}
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
body {
max-width: 400px;
padding: 20px;
margin: auto;
}
input {
display: inline-block;
width: 100%;
padding: 5px 0px 5px 5px;
margin-bottom: 10px;
-webkit-box-sizing: border-box;
‌​ -moz-box-sizing: border-box;
box-sizing: border-box;
}
select {
margin: 5px 0px 15px 0px;
}
input[type="submit"] {
width: auto !important;
display: block !important;
}
input[type="file"] {
padding: 5px 0px 15px 0px !important;
}
#progressbar{
width: 100%;
text-align: center;
overflow: hidden;
position: relative;
vertical-align: middle;
}
.progress-label {
float: left;
margin-top: 5px;
font-weight: bold;
text-shadow: 1px 1px 0 #fff;
width: 100%;
height: 100%;
position: absolute;
vertical-align: middle;
}
</style>
</body>
When deploying as a Spreadsheet container bound app the code is as follows (2 files: Code.gs & form.html):
## Code.gs ##
function uploadFiles() {
function doGet() {
return SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile('form').setSandboxMode(HtmlService.SandboxMode.IFRAME), "Upload Files");
}
doGet();
function uploadFileToDrive(base64Data, fileName, totalFiles, finalCount) {
try{
var splitBase = base64Data.split(','),
type = splitBase[0].split(';')[0].replace('data:','');
var byteCharacters = Utilities.base64Decode(splitBase[1]);
var ss = Utilities.newBlob(byteCharacters, type);
ss.setName(fileName);
var dropbox = "stuff"; // Folder Name
var folder, folders = DriveApp.getFoldersByName(dropbox); // Get folders by name
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var file = folder.createFile(ss);
// BEGIN LOGGING FILE NAMES AND IDs
var dropboxId = "SOME_FOLDER_ID_HERE" // Folder ID
var theFolder = DriveApp.getFolderById(dropboxId); // Get folder by ID
var list = [];
var theBlobs = [];
if (totalFiles == finalCount) {
var files = theFolder.getFiles();
while (files.hasNext()) {
var theFile = files.next();
list.push(theFile.getId());
}
for (var i = 0; i < list.length; i++) {
Logger.log(DriveApp.getFileById(list[i]).getName() + " : " + list[i]);
theBlobs.push(DriveApp.getFileById(list[i]).getBlob());
}
Logger.log(theBlobs);
// END LOGGING FILE NAMES AND IDs
// BEGIN ZIPPING UP FILES
var newZip = theFolder.createFile(Utilities.zip(theBlobs, 'zippedFiles.zip'));
var zipId = newZip.getId();
Logger.log("Zip Id: " + zipId);
// END ZIPPING UP FILES
// BEGIN TRASHING UPLOADED FILES
for (var i = 0; i < list.length; i++) {
DriveApp.getFileById(list[i]).setTrashed(true);
}
// END TRASHING UPLOADED FILES
}
return file.getName();
}catch(e){
return 'Error: ' + e.toString();
}
}
}
## form.html ##
<body>
<div id="formcontainer">
<form id="myForm">
<label for="myFile">Upload File(s):</label><br />
<input type="file" name="filename" id="myFile" multiple />
<input type="button" class="blue" value="Submit" onclick="iteratorFileUpload()" /><br /><br />
</form>
</div>
<div id="output"></div>
<div id="progressbar">
<div class="progress-label"></div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://googledrive.com/host/0By0COpjNTZPnZTBvVGZOSFRhREE/add-ons.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script>
var numUploads = {};
numUploads.done = 0 ;
numUploads.total = 0 ;
// Upload the files into a folder in drive...set to send them all to one folder (specificed in the .gs file)
function iteratorFileUpload() {
var allFiles = document.getElementById('myFile').files;
if (allFiles.length == 0) {
alert('No file selected!');
} else { // Show Progress Bar
var myCount = 0; // Begin count to compare loops through
numUploads.total = allFiles.length;
$('#progressbar').progressbar({
value : false
});
$(".progress-label").html('Preparing files..');
// Send a file at a time
for (var i = 0; i < allFiles.length; i++) {
myCount++; // Increment count each time before sending the file to drive
sendFileToDrive(allFiles[i], allFiles.length, myCount);
}
}
}
function sendFileToDrive(file, totalFiles, newCount) {
var reader = new FileReader();
reader.onload = function (e) {
var content = reader.result;
google.script.run.withSuccessHandler(updateProgressbar).uploadFileToDrive(content, file.name, totalFiles, newCount);
}
reader.readAsDataURL(file);
}
function updateProgressbar( idUpdate ){
numUploads.done++;
var porc = Math.ceil((numUploads.done / numUploads.total)*100);
$("#progressbar").progressbar({value: porc });
$(".progress-label").text(numUploads.done +'/'+ numUploads.total);
if( numUploads.done == numUploads.total ){
numUploads.done = 0;
};
}
/*
function updateProgressbar( idUpdate ){
numUploads.done++;
var porc = Math.ceil((numUploads.done / numUploads.total)*100);
$("#progressbar").progressbar({value: porc });
$(".progress-label").text(numUploads.done +'/'+ numUploads.total);
if( numUploads.done == numUploads.total ){
numUploads.done = 0;
};
}
*/
function fileUploaded(status) {
document.getElementById('myForm').style.display = 'none';
document.getElementById('output').innerHTML = status;
}
</script>
<style>
body {
max-width: 400px;
padding: 20px;
margin: auto;
}
input {
display: inline-block;
width: 100%;
padding: 5px 0px 5px 5px;
margin-bottom: 10px;
-webkit-box-sizing: border-box;
‌​ -moz-box-sizing: border-box;
box-sizing: border-box;
}
select {
margin: 5px 0px 15px 0px;
}
input[type="submit"] {
width: auto !important;
display: block !important;
}
input[type="file"] {
padding: 5px 0px 15px 0px !important;
}
#progressbar{
width: 100%;
text-align: center;
overflow: hidden;
position: relative;
vertical-align: middle;
}
.progress-label {
float: left;
margin-top: 5px;
font-weight: bold;
text-shadow: 1px 1px 0 #fff;
width: 100%;
height: 100%;
position: absolute;
vertical-align: middle;
}
</style>
</body>
The non-working code stops at this point:
google.script.run.withSuccessHandler(updateProgressbar).uploadFileToDrive(content, file.name, totalFiles, newCount);.
Up to that point everything moves along nicely and info is passed from function to function.
In the Spreadsheet script the files never get uploaded to Drive and the counter for the files that displays on the html page never increments...it just stalls.
The closest articles I've come across that may aid in resolving this are: how to use google.script.run as if it was a function that was originally proposed as a solution to this question Google Apps Script HTML Service: Passing variables and Returning a value using Date picker in HTMLService / Google Apps Script.
Thank you for your help in advance!!
The solution was rather simple since the underlying code already functioned as a stand-alone Web App.
The only changes needed made were to the Code.gs file.
Pulled out the beginning of the code and kept it in it's own top-level function:
function uploadFiles() {
function doGet() {
return SpreadsheetApp.getUi().showModalDialog(HtmlService.createHtmlOutputFromFile('form').setSandboxMode(HtmlService.SandboxMode.IFRAME), "Upload Files");
}
doGet();
}
Then put the remainder in it's own top-level function as well:
function uploadFileToDrive(base64Data, fileName, totalFiles, finalCount) {
try{
var splitBase = base64Data.split(','),
type = splitBase[0].split(';')[0].replace('data:','');
var byteCharacters = Utilities.base64Decode(splitBase[1]);
var ss = Utilities.newBlob(byteCharacters, type);
ss.setName(fileName);
var dropbox = "stuff"; // Folder Name
var folder, folders = DriveApp.getFoldersByName(dropbox); // Get folders by name
if (folders.hasNext()) {
folder = folders.next();
} else {
folder = DriveApp.createFolder(dropbox);
}
var file = folder.createFile(ss);
// BEGIN LOGGING FILE NAMES AND IDs
var dropboxId = "SOME_FOLDER_ID_HERE" // Folder ID
var theFolder = DriveApp.getFolderById(dropboxId); // Get folder by ID
var list = [];
var theBlobs = [];
if (totalFiles == finalCount) {
var files = theFolder.getFiles();
while (files.hasNext()) {
var theFile = files.next();
list.push(theFile.getId());
}
for (var i = 0; i < list.length; i++) {
Logger.log(DriveApp.getFileById(list[i]).getName() + " : " + list[i]);
theBlobs.push(DriveApp.getFileById(list[i]).getBlob());
}
Logger.log(theBlobs);
// END LOGGING FILE NAMES AND IDs
// BEGIN ZIPPING UP FILES
var newZip = theFolder.createFile(Utilities.zip(theBlobs, 'zippedFiles.zip'));
var zipId = newZip.getId();
Logger.log("Zip Id: " + zipId);
// END ZIPPING UP FILES
// BEGIN TRASHING UPLOADED FILES
for (var i = 0; i < list.length; i++) {
DriveApp.getFileById(list[i]).setTrashed(true);
}
// END TRASHING UPLOADED FILES
}
return file.getName();
}catch(e){
return 'Error: ' + e.toString();
}
}
It now works perfectly as a script attached to a Spreadsheet!

HTML5 audio player drag and drop

I'm implementing audio player in html5, which has drag-drop option for load and play mp3 files, but I have problem with plaing the file.
When the file is dropped on the area, I can see in the console properties of object, but there is no information about absolute path, because of security in web browser.
Is there an option, how to play mp3 this way ?
index.html and body content:
<div style="border: 1px solid black; width: 200px; height: 50px; padding: 10px;"" id="cudl">add file here</div>
<div id="play" style="border: 1px solid black; width: 200px; height: 50px; padding: 10px;">PLAY</div>
<div id="pause" style="border: 1px solid black; width: 200px; height: 50px; padding: 10px;">PAUSE</div>
<div id="progress" style="width: 1000px; height: 50px; background: black; "><div id="time" style="width: 0%; height: 50px; background: green;"></div></div>
javascript:
window.onload = function () {
var cudl = document.getElementById("cudl");
cudl.addEventListener("dragover", function (ev) {
ev.preventDefault();
}, false);
cudl.addEventListener("drop", function (ev) {
ev.preventDefault();
var data = ev.dataTransfer.getData("audio/mpeg");
var allAudio = document.getElementsByTagName("audio");
if (allAudio.length > 0) {
for (var i = 0; i < allAudio.length; i++) document.body.removeChild(allAudio[i]);
}
var audio = document.createElement("audio");
audio.setAttribute("src", ev.dataTransfer.files[0].name);
document.body.appendChild(audio);
console.log("append file");
console.log(ev.dataTransfer.files[0]);
audio.addEventListener("durationchange", function () {
console.log("dc " + this.duration);
});
audio.addEventListener("timeupdate", function () {
//console.log("ct " + this.currentTime);
var prog = document.getElementById("time");
prog.style.width = Math.floor(this.currentTime / this.duration * 100) + "%";
});
var play = document.getElementById("play");
play.addEventListener("click", function () {
document.getElementsByTagName("audio")[0].play();
});
var pause = document.getElementById("pause");
pause.addEventListener("click", function () {
document.getElementsByTagName("audio")[0].pause();
});
}, false);
};
Instead of using the absolute path to use as an src-attribute on an audio element, I suggest you read the contents of the file(s) and use the webAudio API for decoding the audio data.
Here is a working example for playing the dropped file immediately. But you can just save the buffer for later playback.
var context = new AudioContext()
window.addEventListener('load', function() {
var dropzone = document.querySelector('#dropzone');
dropzone.addEventListener('drop', handleDrop, false)
dropzone.addEventListener('dragover', handleDragOver, false)
})
var handleDragOver = function(e) {
e.preventDefault()
e.stopPropagation()
}
var handleDrop = function(e) {
e.preventDefault()
e.stopPropagation()
var files = e.dataTransfer.files
for (var i = 0; i < files.length; i++) {
var file = files[i]
var reader = new FileReader()
reader.addEventListener('load', function(e) {
var data = e.target.result
context.decodeAudioData(data, function(buffer) {
playSound(buffer)
})
})
reader.readAsArrayBuffer(file)
}
}
var playSound = function(buffer) {
var source = context.createBufferSource()
source.buffer = buffer
source.connect(context.destination)
source.start(0)
}
You can disable the web security of the browser. In the terminal, cd to the application and type "--disable-web-security" without the quotes.
I think you are forgetting to load the audio before playing it. I always forget this when retrieving audio files to play.
document.getElementsByTagName("audio")[0].load();
document.getElementsByTagName("audio")[0].play();

Categories

Resources