Last active
August 29, 2015 13:56
-
-
Save andergmartins/8910448 to your computer and use it in GitHub Desktop.
HTML5 Multiple Files Upload
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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