Skip to content

Instantly share code, notes, and snippets.

@andergmartins
Last active August 29, 2015 13:56
Show Gist options
  • Save andergmartins/8910448 to your computer and use it in GitHub Desktop.
Save andergmartins/8910448 to your computer and use it in GitHub Desktop.
HTML5 Multiple Files Upload
<html>
<head>
<style type="text/css" media="screen">
input {
display: block;
margin-top: 10px;
}
#modal {
background-color: #affdc2;
padding: 20px;
}
#main {
background-color: #fdf0b8;
padding: 20px;
}
#thumbnails {
background: #fff;
min-height: 100px;
border: 1px solid silver;
padding: 5px;
}
#thumbnails img {
max-height: 90px;
margin-left: 5px;
}
</style>
</head>
<body>
<div id="modal">
<h2>Modal</h2>
<!-- Se não vai usar POST (Submit) nem precisa colocar dentro de um form -->
<input type="text" name="feature" id="feature" value="PHP">
<h3>Imagens</h3>
<p>
Você pode selecionar uma imagem ou fazer drag and <drop class=""></drop>
</p>
<input type="file" id="fileSelect" name="fileSelect" multiple="multiple">
<div id="thumbnails">
</div>
<input type="button" value="Save" id="modalSaveButton">
</div>
<div id="main">
<h2>Main Form</h2>
<form id="formPrincipal" method="POST" action="save.php">
<input type="text" name="name" id="name" value="Anderson">
<input type="hidden" name="featureName" id="featureName">
<!-- Não usa um submit, pq precisamos enviar só depois que terminar os uploads -->
<input type="button" value="Save" id="saveButton">
</form>
<h3>File Upload Progress:</h3>
<progress min="0" max="100" value="0" id="fileUploadProgress">0% complete</progress>
</div>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script>
// Inicia a lista de arquivos para upload, vazia.
// Pode ser qualquer variável JS global, mas pode ser um data do form
// Vou tratar como se houvesse apenas um "Diferencial", com id 346
// (id existente ou um q vc criou dinamicamente ao inserir e antes de salvar)
var filesToUpload = [];
var modalFiles = [];
// Usado para saber o total geral de arquivos, para identificar quando terminaram todos os uploads
totalFilesToUpload = 0;
// Detecta novo arquivo selecionado sem drag and drop
$("#fileSelect").on("change", function(e) {
var file;
// Pega os arquivos selecionados
var files = e.target.files;
for (var i = 0; i < files.length; i++) {
file = files[i];
// Lê o arquivo e cria o thumbnail
var readerThumb = new FileReader();
readerThumb.onload = function(e) {
var thumb = $('<img>').attr('src', e.target.result);
$('#thumbnails').append(thumb);
}
readerThumb.readAsDataURL(file);
// Armazena o arquivo selecionado para fazer upload depois
modalFiles.push(file);
totalFilesToUpload++;
}
});
// Save, do modal
$('#modalSaveButton').on('click', function() {
// Isso vc já tem funcionando... mas estou fazendo só com um, pra ganhar tempo
$('#featureName').val($('#feature').val());
// Essa é a parte da imagem, aqui estou só substituindo,
// mas vc precisa ver se há algum item, para não sobrescrever caso
// a pessoa visite o modal para o mesmo "Diferencial"
var file;
for (var i = 0; i < modalFiles.length; i++) {
file = modalFiles[i];
filesToUpload.push({
id: 346,
file: file
});
}
// Limpa o modal
$('#thumbnails').html('');
modalFiles = [];
});
// Cuida do Submit, do form principal, para fazer os uploads antes de salvar tudo
$('#saveButton').on('click', function() {
var uploadFile = function(i) {
// Existe uma imagem para enviar com este índice?
if (i < filesToUpload.length) {
var item = filesToUpload[i];
// Lê o arquivo para pegar os dados binários
var reader = new FileReader();
reader.onload = function(evt) {
// create XHR instance
xhr = new XMLHttpRequest();
// send the file through POST
xhr.open("POST", 'upload.php', true);
// Envia o nome do arquivo para referencia no POST principal
// Assim poderá linkar o arquivo aos registros
// Coloca um nome único, aleatório
var tmpName = new Date().getTime() + '';
tmpName += Math.floor(Math.random() * 9999999999);
// Adiciona a extensão, para poder saber depois ao mover o arquivo temporário
tmpName += '_' + item.file.name.match(/\.([a-zA-Z0-9]*)$/)[1];
xhr.setRequestHeader('Upload-Tmp-Name', tmpName);
// make sure we have the sendAsBinary method on all browsers
XMLHttpRequest.prototype.mySendAsBinary = function(text){
var data = new ArrayBuffer(text.length);
var ui8a = new Uint8Array(data, 0);
for (var i = 0; i < text.length; i++) ui8a[i] = (text.charCodeAt(i) & 0xff);
if(typeof window.Blob == "function") {
var blob = new Blob([data]);
} else {
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(data);
var blob = bb.getBlob();
}
this.send(blob);
}
// // let's track upload progress
// var eventSource = xhr.upload || xhr;
// eventSource.addEventListener("progress", function(e) {
// // get percentage of how much of the current file has been sent
// var position = e.position || e.loaded;
// var total = e.totalSize || e.total;
// var percentage = Math.round((position/total)*100);
// // here you should write your own code how you wish to proces this
// var progressBar = $('#fileUploadProgress');
// progressBar.value = (e.loaded / e.total) * 100;
// progressBar.textContent = progressBar.value; // Fallback for unsupported browsers.
// });
// state change observer - we need to know when and if the file was successfully uploaded
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
if(xhr.status == 200) {
// Sucesso no Upload!!
// Adiciona no form principal, um input hidden, para saber quais imagens deve ligar
var input = $('<input type="hidden">');
input.attr('name', 'files[]');
// Concatena o ID do "Diferencial" para saber de quem é a imagem
input.val(item.id + '_' + tmpName);
$('#formPrincipal').append(input);
} else {
alert('Erro ao fazer upload do arquivo: ' + item.file.name);
}
// Vamos para a próxima imagem.
uploadFile(i+1);
}
};
// start sending
xhr.mySendAsBinary(evt.target.result);
};
reader.readAsBinaryString(item.file);
} else {
// Acabaram as imagens, então chamamos o form submit
$('#formPrincipal').submit();
}
};
// Percorre a lista de "Diferenciais" para upload das imagens, recursivamente
uploadFile(0);
});
</script>
</body>
</html>
<?php
var_dump($_POST);
// Vc tem, na pasta tmp as imagens temporárias, então é só mover para sua pasta Media
// e registrar no db de acordo com o id do "Diferencial"
// Vamos assumir que o ID do imóvel é 45.
foreach ($_POST['files'] as $file) {
$item = explode('_', $file);
var_dump($item);
}
<?php
// read contents from the input stream
$inputHandler = fopen('php://input', "r");
// Extrai o nome, do header Upload-Tmp-Name. O nome deste header pode ser alterado, no JS e posteriormente aqui
$tmpName = $_SERVER['HTTP_UPLOAD_TMP_NAME'];
// create a temp file where to save data from the input stream
$fileHandler = fopen('tmp/' . $tmpName . '.tmp', "w+");
// save data from the input stream
while(true) {
$buffer = fgets($inputHandler, 4096);
if (strlen($buffer) == 0) {
fclose($inputHandler);
fclose($fileHandler);
break;
}
fwrite($fileHandler, $buffer);
}
echo 'OK';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment